<?xml version='1.0' encoding='utf-8'?>
<Benchmark xmlns="http://checklists.nist.gov/xccdf/1.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xhtml="http://www.w3.org/1999/xhtml" id="xccdf_org.adhardening.benchmarks_benchmark_ad-hardening" resolved="false" xml:lang="en">
  <status date="2026-09-09">accepted</status>
  <title>Active Directory Hardening Guidebook Benchmark</title>
  <description>Automated compliance checklist profiles and rules parsed directly from the Active Directory Hardening Guidebook.</description>
  <version>1.0</version>
  <metadata>
    <dc:publisher>Antigravity Hardening Project</dc:publisher>
    <dc:creator>Antigravity</dc:creator>
    <dc:date>2026-09-09</dc:date>
  </metadata>
  <Profile id="xccdf_org.adhardening.benchmarks_profile_DomainController">
    <title>Domain Controller Hardening Profile</title>
    <description>Applies all Tier 0 infrastructure and Domain Controller security checks.</description>
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-013" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-014" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-015" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-016" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-017" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-018" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-019" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-021" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-022" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-024" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-025" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-027" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-028" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-029" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-030" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-031" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-032" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-033" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-034" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-035" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-036" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-037" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-038" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-039" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-040" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-041" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-042" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-043" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-044" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-045" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-046" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-047" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-048" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-049" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-050" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-051" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-052" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-053" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-054" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-055" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-056" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-057" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-058" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-059" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-060" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-061" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-062" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-063" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-064" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-065" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-066" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-067" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-068" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-069" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-070" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-071" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-072" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-073" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-074" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-075" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-076" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-077" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-078" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-079" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-080" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-081" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-082" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-083" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-084" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-085" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-086" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-087" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-088" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-090" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-091" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-092" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-093" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-094" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-095" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-096" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-097" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-098" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-099" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-100" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-101" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-102" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-103" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-104" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-105" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-106" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-107" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-108" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-109" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-110" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-111" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-112" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-113" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-114" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-115" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-116" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-117" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-118" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-119" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-120" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-121" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-122" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-123" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-124" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-125" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-126" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-127" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-128" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-129" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-130" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-131" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-132" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-133" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-134" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-135" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-136" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-137" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-138" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-139" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-140" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-141" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-142" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-143" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-144" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-145" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-146" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-147" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-148" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-149" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-150" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-151" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-152" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-153" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-154" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-155" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-156" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-157" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-158" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-159" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-DC-160" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-013" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-014" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-015" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-016" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-017" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-018" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-019" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-020" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-013" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-013" selected="true" />
  </Profile>
  <Profile id="xccdf_org.adhardening.benchmarks_profile_PAW">
    <title>Privileged Access Workstations (PAW) Hardening Profile</title>
    <description>Applies security restrictions specifically targeting PAWs.</description>
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-016" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-014" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-015" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-016" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-017" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-018" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-019" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-020" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-021" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-022" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-023" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-025" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-026" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-027" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-030" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-031" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-032" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-033" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-034" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-035" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-036" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-037" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-038" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-039" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-040" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-041" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-042" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-043" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-044" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-045" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-046" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-047" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-048" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-049" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-050" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-051" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-052" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-053" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-054" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-055" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-056" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-057" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-058" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-059" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-060" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-061" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-062" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-063" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-064" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-065" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-066" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-067" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-068" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-069" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-071" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-072" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-073" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-074" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-075" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-076" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-077" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-078" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-079" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-080" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-081" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-082" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-083" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-084" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-085" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-086" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-087" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-088" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-089" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-090" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-091" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-092" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-093" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-094" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-095" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-096" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-097" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-098" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-099" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-100" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-101" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-102" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-103" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-104" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-105" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-106" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-107" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-108" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-109" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-110" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-111" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-112" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-113" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-114" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-115" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-116" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-117" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-118" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-119" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-120" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-121" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-122" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-123" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-124" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-125" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-126" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-127" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-128" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-130" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-131" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-132" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-133" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-135" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-136" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-137" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-138" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-139" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-140" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-141" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-142" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-143" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-144" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-145" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-146" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-147" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-148" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-149" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-150" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-151" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-152" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-153" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-154" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-155" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-156" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-157" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-158" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-159" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-160" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-161" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-162" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-163" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-164" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-165" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-166" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-167" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-168" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-169" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-170" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-171" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-172" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-173" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-174" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-175" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-176" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-177" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-178" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-179" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-180" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-181" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-182" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-183" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-184" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-185" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-186" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-187" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-188" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-189" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-190" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-191" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-192" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-193" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-194" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-195" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-196" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-197" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-198" selected="true" />
  </Profile>
  <Profile id="xccdf_org.adhardening.benchmarks_profile_Endpoint">
    <title>Endpoint Hardening Profile</title>
    <description>Applies security baselines for general client workstations and endpoints.</description>
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-011" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-012" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-013" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-014" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-015" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-017" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-020" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-021" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-022" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-023" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-025" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-027" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-028" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-029" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-030" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-031" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-032" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-033" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-034" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-035" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-036" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-037" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-038" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-039" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-040" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-041" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-042" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-043" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-044" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-045" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-046" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-047" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-048" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-049" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-050" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-051" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-052" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-053" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-054" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-055" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-056" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-057" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-058" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-059" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-060" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-061" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-062" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-063" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-064" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-065" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-066" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-067" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-068" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-069" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-070" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-072" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-073" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-074" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-075" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-076" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-077" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-078" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-079" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-080" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-081" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-082" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-083" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-084" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-085" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-086" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-087" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-088" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-089" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-090" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-091" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-092" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-093" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-094" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-095" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-096" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-097" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-098" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-099" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-100" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-101" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-102" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-103" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-104" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-105" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-106" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-107" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-108" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-109" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-110" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-111" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-112" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-113" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-114" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-115" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-116" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-117" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-118" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-119" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-120" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-121" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-122" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-123" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-124" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-125" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-126" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-127" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-128" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-129" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-130" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-131" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-132" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-133" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-134" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-135" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-136" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-137" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-138" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-139" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-141" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-142" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-143" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-144" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-146" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-147" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-148" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-149" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-150" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-151" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-152" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-153" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-154" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-155" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-156" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-157" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-158" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-159" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-160" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-161" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-162" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-163" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-164" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-165" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-166" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-167" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-168" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-169" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-170" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-171" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-172" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-173" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-174" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-175" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-176" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-177" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-178" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-179" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-180" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-181" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-182" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-183" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-184" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-185" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-186" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-187" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-188" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-189" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-190" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-191" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-192" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-193" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-194" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-195" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-196" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-197" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-198" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-199" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-200" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-201" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-202" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-203" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-204" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-205" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-206" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-207" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-208" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-END-209" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-ID-016" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-002" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-001" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-005" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-006" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-007" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-008" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-009" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-NET-010" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-003" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-004" selected="true" />
    <select idref="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-012" selected="true" />
  </Profile>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_1__Architecture___Administrative_Tiering">
    <title>Module 1: Architecture &amp; Administrative Tiering</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-001] Implement Active Directory Administrative Tiering Model</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 1 member servers and Tier 2 client workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/implement-administrative-tiering-model.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>To successfully enforce the administrative tiering model, the boundaries must be programmatically restricted. Active Directory administrative groups (such as <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, and <xhtml:code>Schema Admins</xhtml:code>) must be explicitly blocked from authenticating to lower-tier systems.</xhtml:p>
        <xhtml:p>If these permissions are not restricted, a Tier 0 administrator might use their account to troubleshoot a Tier 1 server or Tier 2 workstation. This action caches their administrative password hash or Kerberos Ticket Granting Ticket (TGT) in the local memory of the target machine. If that machine has been compromised, an attacker can extract those credentials and compromise the entire Active Directory domain.</xhtml:p>
        <xhtml:p>By configuring Group Policy objects to explicitly deny logon rights (interactive, network, and Remote Desktop) for high-tier administrative accounts on lower-tier systems, you prevent accidental or unauthorized exposure of high-privilege credentials.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To prevent Tier 0 credentials from being exposed on Tier 1 and Tier 2 systems, configure the logon restrictions using GPOs linked to the Tier 1 (Member Servers) and Tier 2 (Workstations) OUs.</xhtml:p>
        <xhtml:h4>1. Configure Tier 1 Logon Restrictions GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create a GPO linked to the <xhtml:strong>Tier 1 Member Servers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Restrictions_Tier1</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
          </xhtml:li>
          <xhtml:li>Define and configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny access to this computer from the network</xhtml:em>*: Add <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on as a batch job</xhtml:em>*: Add <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on as a service</xhtml:em>*: Add <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on locally</xhtml:em>*: Add <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on through Remote Desktop Services</xhtml:em>*: Add <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Tier 2 Logon Restrictions GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Create a GPO linked to the <xhtml:strong>Tier 2 Workstations</xhtml:strong> OU (e.g., <xhtml:code>GPO_Restrictions_Tier2</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to the same path:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the policies to deny access for <xhtml:strong>both</xhtml:strong> Tier 0 and Tier 1 administrative groups:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny access to this computer from the network</xhtml:em>*: Add Tier 0 groups (<xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>) and Tier 1 administrative groups.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on as a batch job</xhtml:em>*: Add Tier 0 and Tier 1 administrative groups.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on as a service</xhtml:em>*: Add Tier 0 and Tier 1 administrative groups.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on locally</xhtml:em>*: Add Tier 0 and Tier 1 administrative groups.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Deny log on through Remote Desktop Services</xhtml:em>*: Add Tier 0 and Tier 1 administrative groups.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this script to configure local security database files via <xhtml:code>secedit</xhtml:code> to deny specified administrative groups from logging on locally, over the network, or via Remote Desktop.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-LocalLogonRestrictions.ps1">Download Script: Set-LocalLogonRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-LocalLogonRestrictions.ps1
# Configures secedit User Rights Assignment to block domain administrative groups.

# 1. Define groups to block (Tier 0 admin groups)
$DenyGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins")

# 2. Translate group names to SID strings
$SIDs = foreach ($group in $DenyGroups) {
    try {
        $sid = (New-Object System.Security.Principal.NTAccount($group)).Translate([System.Security.Principal.SecurityIdentifier]).Value
        "*$sid"
    } catch {
        Write-Warning "Could not resolve SID for group: $group. Skipping."
    }
}

if ($SIDs.Count -eq 0) {
    Write-Error "No valid group SIDs resolved. Exiting."
    exit 1
}

# 3. Define the temporary paths for secedit config
$tempDir = [System.IO.Path]::GetTempPath()
$secConfigPath = Join-Path $tempDir "sec_config.inf"
$secDbPath = Join-Path $tempDir "sec_db.sdb"

# 4. Export current local security policy
secedit /export /cfg $secConfigPath /areas USER_RIGHTS /quiet

# 5. Modify exported config to inject our deny rules
$configContent = Get-Content -Path $secConfigPath
$NewContent = [System.Collections.Generic.List[string]]::new()
$InUserRights = $false

$PolicyEntries = @(
    "SeDenyInteractiveLogonRight",
    "SeDenyNetworkLogonRight",
    "SeDenyRemoteInteractiveLogonRight"
)

foreach ($line in $configContent) {
    if ($line -match '^\[Privilege Rights\]') {
        $InUserRights = $true
        $NewContent.Add($line)
        continue
    }
    if ($InUserRights -and $line -match '^\[') {
        $InUserRights = $false
    }
    
    # Filter out existing lines for the policies we configure
    $matched = $false
    foreach ($entry in $PolicyEntries) {
        if ($line -match "^$entry\s*=") {
            $matched = $true
            break
        }
    }
    
    if (-not $matched) {
        $NewContent.Add($line)
    }
}

# Insert new rules into [Privilege Rights] section
$InsertIndex = $NewContent.FindIndex({ $args[0] -match '^\[Privilege Rights\]' })
if ($InsertIndex -ge 0) {
    $Offset = 1
    $FormattedSIDs = $SIDs -join ","
    foreach ($policy in $PolicyEntries) {
        $NewContent.Insert($InsertIndex + $Offset, "$policy = $FormattedSIDs")
        $Offset++
    }
}

# Save new configuration
$NewContent | Out-File -FilePath $secConfigPath -Encoding utf16

# 6. Apply configuration using secedit
Write-Host "Applying User Rights Assignment restrictions via secedit..." -ForegroundColor Cyan
$process = Start-Process secedit -ArgumentList "/configure /db $secDbPath /cfg $secConfigPath /areas USER_RIGHTS /quiet" -Wait -NoNewWindow -PassThru

# Cleanup temporary database files
if (Test-Path $secConfigPath) { Remove-Item $secConfigPath -Force }
if (Test-Path $secDbPath) { Remove-Item $secDbPath -Force }

if ($process.ExitCode -eq 0) {
    Write-Host "Logon restrictions applied successfully." -ForegroundColor Green
} else {
    Write-Error "Failed to apply logon restrictions. Exit code: $($process.ExitCode)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit active logon restriction settings locally:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-LocalLogonRestrictions.ps1">Download Script: Test-LocalLogonRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-LocalLogonRestrictions.ps1
# Audits local security policies to check if SeDeny rights are populated.

Write-Host "--- Auditing Local User Rights Assignments ---" -ForegroundColor Cyan

$tempDir = [System.IO.Path]::GetTempPath()
$secConfigPath = Join-Path $tempDir "sec_audit.inf"

# Export current configuration
secedit /export /cfg $secConfigPath /areas USER_RIGHTS /quiet

$configContent = Get-Content -Path $secConfigPath
$PoliciesToTest = @(
    "SeDenyInteractiveLogonRight",
    "SeDenyNetworkLogonRight",
    "SeDenyRemoteInteractiveLogonRight"
)

foreach ($policy in $PoliciesToTest) {
    $match = $configContent | Where-Object { $_ -match "^$policy\s*=" }
    if ($match) {
        # Check if it contains domain admin or other groups
        Write-Host "    - Policy '$policy' is configured: $match" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: Policy '$policy' is not defined (No accounts denied)." -ForegroundColor Red
    }
}

if (Test-Path $secConfigPath) { Remove-Item $secConfigPath -Force }</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-LocalLogonRestrictions.ps1
# Configures secedit User Rights Assignment to block domain administrative groups.

# 1. Define groups to block (Tier 0 admin groups)
$DenyGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins")

# 2. Translate group names to SID strings
$SIDs = foreach ($group in $DenyGroups) {
    try {
        $sid = (New-Object System.Security.Principal.NTAccount($group)).Translate([System.Security.Principal.SecurityIdentifier]).Value
        "*$sid"
    } catch {
        Write-Warning "Could not resolve SID for group: $group. Skipping."
    }
}

if ($SIDs.Count -eq 0) {
    Write-Error "No valid group SIDs resolved. Exiting."
    exit 1
}

# 3. Define the temporary paths for secedit config
$tempDir = [System.IO.Path]::GetTempPath()
$secConfigPath = Join-Path $tempDir "sec_config.inf"
$secDbPath = Join-Path $tempDir "sec_db.sdb"

# 4. Export current local security policy
secedit /export /cfg $secConfigPath /areas USER_RIGHTS /quiet

# 5. Modify exported config to inject our deny rules
$configContent = Get-Content -Path $secConfigPath
$NewContent = [System.Collections.Generic.List[string]]::new()
$InUserRights = $false

$PolicyEntries = @(
    "SeDenyInteractiveLogonRight",
    "SeDenyNetworkLogonRight",
    "SeDenyRemoteInteractiveLogonRight"
)

foreach ($line in $configContent) {
    if ($line -match '^\[Privilege Rights\]') {
        $InUserRights = $true
        $NewContent.Add($line)
        continue
    }
    if ($InUserRights -and $line -match '^\[') {
        $InUserRights = $false
    }
    
    # Filter out existing lines for the policies we configure
    $matched = $false
    foreach ($entry in $PolicyEntries) {
        if ($line -match "^$entry\s*=") {
            $matched = $true
            break
        }
    }
    
    if (-not $matched) {
        $NewContent.Add($line)
    }
}

# Insert new rules into [Privilege Rights] section
$InsertIndex = $NewContent.FindIndex({ $args[0] -match '^\[Privilege Rights\]' })
if ($InsertIndex -ge 0) {
    $Offset = 1
    $FormattedSIDs = $SIDs -join ","
    foreach ($policy in $PolicyEntries) {
        $NewContent.Insert($InsertIndex + $Offset, "$policy = $FormattedSIDs")
        $Offset++
    }
}

# Save new configuration
$NewContent | Out-File -FilePath $secConfigPath -Encoding utf16

# 6. Apply configuration using secedit
Write-Host "Applying User Rights Assignment restrictions via secedit..." -ForegroundColor Cyan
$process = Start-Process secedit -ArgumentList "/configure /db $secDbPath /cfg $secConfigPath /areas USER_RIGHTS /quiet" -Wait -NoNewWindow -PassThru

# Cleanup temporary database files
if (Test-Path $secConfigPath) { Remove-Item $secConfigPath -Force }
if (Test-Path $secDbPath) { Remove-Item $secDbPath -Force }

if ($process.ExitCode -eq 0) {
    Write-Host "Logon restrictions applied successfully." -ForegroundColor Green
} else {
    Write-Error "Failed to apply logon restrictions. Exit code: $($process.ExitCode)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-002] Restrict Administrative Management Protocols</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 0 assets (Domain Controllers, Jump Hosts) and Tier 1 member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/restrict-mgmt-protocols.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Remote management protocols like Remote Desktop Protocol (RDP) and Windows Remote Management (WinRM) are critical interfaces for directory administration. However, if these protocols are accessible from any host in the network, they become high-value targets for attackers.</xhtml:p>
        <xhtml:p>If an attacker compromises a standard user workstation (Tier 2), they can run network scanners to identify all machines listening on port 3389 (RDP) or 5985/5986 (WinRM). They can then attempt password spraying or locate open administrative sessions.</xhtml:p>
        <xhtml:p>Restricting administrative protocols at the network and local firewall levels to allow inbound connections <xhtml:em>only</xhtml:em> from designated administrative jump hosts or PAW IP ranges stops lateral movement and brute-force attempts from standard user networks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit the GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Expand <xhtml:strong>Inbound Rules</xhtml:strong>.</xhtml:li>
          <xhtml:li>Locate the rule <xhtml:strong>Remote Desktop - User Mode (TCP-In)</xhtml:strong> (or create a custom inbound port rule for TCP port 3389).</xhtml:li>
          <xhtml:li>Double-click the rule, navigate to the <xhtml:strong>Scope</xhtml:strong> tab, and configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Remote IP address</xhtml:em>
            <xhtml:em>: Click </xhtml:em>
            <xhtml:em>These IP addresses</xhtml:em>* and enter the specific IP range of the Tier 0 Jump Hosts and PAWs (e.g., <xhtml:code>10.10.0.0/24</xhtml:code>). Do not allow "Any IP address".</xhtml:li>
          <xhtml:li>Locate the rule <xhtml:strong>Windows Remote Management (HTTP-In)</xhtml:strong> (TCP port 5985/5986).</xhtml:li>
          <xhtml:li>Double-click the rule, navigate to the <xhtml:strong>Scope</xhtml:strong> tab, and enter the same administrative IP range under <xhtml:strong>Remote IP address</xhtml:strong>.</xhtml:li>
          <xhtml:li>Enforce blocking of any other inbound connections by ensuring the default firewall action for the profile is set to block inbound connections that do not match an allow rule.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on a Domain Controller or member server to create Windows Defender Firewall rules restricting WinRM and RDP to authorized subnets.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-AdminProtocolRestrictions.ps1">Download Script: Set-AdminProtocolRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-AdminProtocolRestrictions.ps1
# Creates inbound firewall rules to restrict RDP and WinRM to designated management subnets.

Write-Host "--- Restricting Administrative Protocols Inbound ---" -ForegroundColor Cyan

# Define the authorized administrative network subnet
$AdminSubnet = "10.10.0.0/24" # Replace with your PAW / Jump Host subnet

# 1. Restrict RDP (TCP port 3389) Inbound
$RdpRule = Get-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" -ErrorAction SilentlyContinue
if ($RdpRule) {
    Write-Host "[+] Restricting existing RDP firewall rule to admin subnet..." -ForegroundColor Gray
    Set-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" -RemoteAddress $AdminSubnet
    Write-Host "    RDP rule restricted." -ForegroundColor Green
} else {
    Write-Host "[+] Creating new restricted RDP inbound rule..." -ForegroundColor Gray
    New-NetFirewallRule -DisplayName "Hardening: Restricted RDP Inbound" `
        -Direction Inbound `
        -Action Allow `
        -Protocol TCP `
        -LocalPort 3389 `
        -RemoteAddress $AdminSubnet `
        -Enabled True | Out-Null
    Write-Host "    Restricted RDP rule created." -ForegroundColor Green
}

# 2. Restrict WinRM HTTPS (TCP port 5986) Inbound
$WinRMRule = Get-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -ErrorAction SilentlyContinue
if ($WinRMRule) {
    Write-Host "[+] Restricting existing WinRM HTTPS rule to admin subnet..." -ForegroundColor Gray
    Set-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -RemoteAddress $AdminSubnet
    Write-Host "    WinRM rule restricted." -ForegroundColor Green
} else {
    Write-Host "[+] Creating new restricted WinRM HTTPS inbound rule..." -ForegroundColor Gray
    New-NetFirewallRule -DisplayName "Hardening: Restricted WinRM HTTPS Inbound" `
        -Direction Inbound `
        -Action Allow `
        -Protocol TCP `
        -LocalPort 5986 `
        -RemoteAddress $AdminSubnet `
        -Enabled True | Out-Null
    Write-Host "    Restricted WinRM rule created." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the firewall restrictions:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-AdminProtocolRestrictions.ps1">Download Script: Test-AdminProtocolRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-AdminProtocolRestrictions.ps1
# Audits local firewall rules for RDP and WinRM to check remote address restrictions.

Write-Host "--- Auditing Administrative Port Firewall Rules ---" -ForegroundColor Cyan

$Rules = @(
    "Remote Desktop - User Mode (TCP-In)",
    "Windows Remote Management (HTTPS-In)",
    "Hardening: Restricted RDP Inbound",
    "Hardening: Restricted WinRM HTTPS Inbound"
)

foreach ($RuleName in $Rules) {
    $Rule = Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue
    if ($Rule) {
        $Address = Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $Rule
        $color = if ($Address.RemoteAddress -ne "Any" -and $Address.RemoteAddress -ne "") { "Green" } else { "Red" }
        Write-Host "    - Firewall Rule: $($Rule.DisplayName) | Enabled: $($Rule.Enabled) | RemoteAddress Restriction: $($Address.RemoteAddress)" -ForegroundColor $color
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-AdminProtocolRestrictions.ps1
# Creates inbound firewall rules to restrict RDP and WinRM to designated management subnets.

Write-Host "--- Restricting Administrative Protocols Inbound ---" -ForegroundColor Cyan

# Define the authorized administrative network subnet
$AdminSubnet = "10.10.0.0/24" # Replace with your PAW / Jump Host subnet

# 1. Restrict RDP (TCP port 3389) Inbound
$RdpRule = Get-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" -ErrorAction SilentlyContinue
if ($RdpRule) {
    Write-Host "[+] Restricting existing RDP firewall rule to admin subnet..." -ForegroundColor Gray
    Set-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" -RemoteAddress $AdminSubnet
    Write-Host "    RDP rule restricted." -ForegroundColor Green
} else {
    Write-Host "[+] Creating new restricted RDP inbound rule..." -ForegroundColor Gray
    New-NetFirewallRule -DisplayName "Hardening: Restricted RDP Inbound" `
        -Direction Inbound `
        -Action Allow `
        -Protocol TCP `
        -LocalPort 3389 `
        -RemoteAddress $AdminSubnet `
        -Enabled True | Out-Null
    Write-Host "    Restricted RDP rule created." -ForegroundColor Green
}

# 2. Restrict WinRM HTTPS (TCP port 5986) Inbound
$WinRMRule = Get-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -ErrorAction SilentlyContinue
if ($WinRMRule) {
    Write-Host "[+] Restricting existing WinRM HTTPS rule to admin subnet..." -ForegroundColor Gray
    Set-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -RemoteAddress $AdminSubnet
    Write-Host "    WinRM rule restricted." -ForegroundColor Green
} else {
    Write-Host "[+] Creating new restricted WinRM HTTPS inbound rule..." -ForegroundColor Gray
    New-NetFirewallRule -DisplayName "Hardening: Restricted WinRM HTTPS Inbound" `
        -Direction Inbound `
        -Action Allow `
        -Protocol TCP `
        -LocalPort 5986 `
        -RemoteAddress $AdminSubnet `
        -Enabled True | Out-Null
    Write-Host "    Restricted WinRM rule created." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-003] Audit Privileged Groups</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above) Domain Controllers.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/audit-privileged-groups.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Attackers who gain initial access to an Active Directory domain attempt to elevate their privileges to Tier 0. A primary method for establishing domain persistence is adding compromised domain accounts to highly privileged administrative groups, such as <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>, or <xhtml:code>Builtin\Administrators</xhtml:code>.</xhtml:p>
        <xhtml:p>If these groups are not audited continuously: 1. <xhtml:strong>Backdoor Persistence</xhtml:strong>: Attackers can add temporary users to administrative groups and remove them later, leaving backdoor accounts with administrative authority that go unnoticed. 2. <xhtml:strong>Privilege Creep</xhtml:strong>: Unmanaged administrative accounts accumulate over time, violating the principle of least privilege. 3. <xhtml:strong>Delegation Risks</xhtml:strong>: Administrative accounts can inherit unintended administrative rights if nested within other groups.</xhtml:p>
        <xhtml:p>Enforcing advanced auditing on directory object changes, combined with a daily script to monitor privileged group members, ensures immediate visibility into unauthorized modifications.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To generate events when administrative group membership is altered: 1. Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>). 2. Create or edit the GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>). 3. Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Advanced Audit Policy Configuration\Audit Policies\DS Access</xhtml:code> 4. Configure the setting: <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Audit Directory Service Changes` </xhtml:em>
          <xhtml:strong>Setting</xhtml:strong>: <xhtml:code>Enabled</xhtml:code> (Select <xhtml:code>Success</xhtml:code> and <xhtml:code>Failure</xhtml:code>)</xhtml:p>
        <xhtml:p>This ensures that Event ID <xhtml:strong>5136</xhtml:strong> is logged in the Security log of the Domain Controller whenever an Active Directory object attribute (such as a group's <xhtml:code>member</xhtml:code> attribute) is changed.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run this script from a secure administrative workstation to audit nested and direct memberships in critical Tier 0 groups, highlighting any unexpected accounts.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-ADAdminGroups.ps1">Download Script: Audit-ADAdminGroups.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-ADAdminGroups.ps1
# Queries memberships of privileged Tier 0 AD groups recursively.

Import-Module ActiveDirectory

$Tier0Groups = @(
    "Domain Admins",
    "Enterprise Admins",
    "Schema Admins",
    "Administrators",
    "Account Operators",
    "Server Operators",
    "Backup Operators"
)

Write-Host "--- Auditing Privileged AD Groups ---" -ForegroundColor Cyan

# Define the list of explicitly authorized accounts (e.g. emergency break-glass account)
$AuthorizedUsers = @("Administrator", "a0-breakglass")

foreach ($GroupName in $Tier0Groups) {
    try {
        $Group = Get-ADGroup -Identity $GroupName -ErrorAction Stop
        $Members = Get-ADGroupMember -Identity $GroupName -Recursive
        
        Write-Host "`n[+] Group: $($Group.Name)" -ForegroundColor Yellow
        if ($Members.Count -eq 0) {
            Write-Host "    No members found." -ForegroundColor Gray
        } else {
            foreach ($Member in $Members) {
                # Highlight unauthorized accounts in red
                if ($AuthorizedUsers -notcontains $Member.SamAccountName -and $Member.SamAccountName -notlike "a0-*") {
                    Write-Host "    - VULNERABLE: Unauthorized user '$($Member.SamAccountName)' in admin group!" -ForegroundColor Red
                } else {
                    Write-Host "    - Member: $($Member.SamAccountName) | Class: $($Member.objectClass)" -ForegroundColor Green
                }
            }
        }
    } catch {
        Write-Warning "Could not query group '$GroupName'. Ensure appropriate permissions."
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that directory auditing is active on the local DC:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-ADChangesAuditing.ps1">Download Script: Test-ADChangesAuditing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-ADChangesAuditing.ps1
# Audits local DC auditpol settings to verify Directory Service auditing is enabled.

Write-Host "--- Auditing Directory Service Audit Policy ---" -ForegroundColor Cyan

$rawOutput = auditpol.exe /get /subcategory:"Directory Service Changes" /r
# Parse CSV output: Machine,Subcategory,GUID,PolicyVal
if ($rawOutput -match "^.+,Directory Service Changes,.+,(.+)$") {
    $policyVal = $Matches[1]
    $color = if ($policyVal -match "Success") { "Green" } else { "Red" }
    Write-Host "    - Directory Service Changes Audit: $policyVal (Required = Success and Failure)" -ForegroundColor $color
} else {
    Write-Warning "    - Status: Could not parse DS auditpol status."
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-004" severity="medium" weight="10.0" selected="false">
      <title>[REQ-ARCH-004] Keep Domain and Forest Functional Levels Up-To-Date</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Forest-wide configuration)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/keep-functional-levels-up-to-date.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Domain Functional Level (DFL) and Forest Functional Level (FFL) dictate the capabilities of the Active Directory (AD) infrastructure. While upgrading the Operating System of Domain Controllers (DCs) improves the underlying OS security, the AD logic remains constrained by the functional level. Maintaining an obsolete DFL forces Domain Controllers to emulate legacy behaviors and protocols to ensure backward compatibility with non-existent older DCs. This emulation effectively creates a ceiling for your security posture, preventing the activation of modern identity protection mechanisms.</xhtml:p>
        <xhtml:p>Raising the functional level is critical for hardening because it unlocks architectural security changes that mitigate credential theft and lateral movement. Specifically, higher functional levels are prerequisites for: 1. <xhtml:strong>Protected Users Group</xhtml:strong>: Mandates restrictions that prevent caching of NTLM credentials, disable Kerberos DES/RC4 keys, and prevent caching of plaintext passwords. 2. <xhtml:strong>Group Managed Service Accounts (gMSAs)</xhtml:strong>: Eliminates static service account passwords by automating 120-character key rotation. 3. <xhtml:strong>Kerberos Armoring (FAST)</xhtml:strong>: Protects Kerberos tickets and exchanges against offline dictionary attacks and ticket manipulation. 4. <xhtml:strong>Deprecating Legacy Replication</xhtml:strong>: Disables insecure File Replication Service (FRS) in favor of DFS Replication (DFSR).</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Domains and Trusts (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller or a management workstation with <xhtml:strong>Enterprise Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Active Directory Domains and Trusts</xhtml:strong> console (<xhtml:code>domain.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>To raise the Domain Functional Level:</xhtml:li>
          <xhtml:li>
            <xhtml:em> In the console tree, right-click the domain for which you want to raise the functional level, and then click </xhtml:em>
            <xhtml:em>Raise Domain Functional Level</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select </xhtml:em>
            <xhtml:em>Windows Server 2016</xhtml:em>
            <xhtml:em> (or higher depending on your environment) from the list of available levels, and then click </xhtml:em>
            <xhtml:em>Raise</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Read the warning dialog and click </xhtml:em>
            <xhtml:em>OK</xhtml:em>* to confirm.</xhtml:li>
          <xhtml:li>To raise the Forest Functional Level:</xhtml:li>
          <xhtml:li>
            <xhtml:em> In the console tree, right-click </xhtml:em>
            <xhtml:em>Active Directory Domains and Trusts</xhtml:em>
            <xhtml:em>, and then click </xhtml:em>
            <xhtml:em>Raise Forest Functional Level</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select </xhtml:em>
            <xhtml:em>Windows Server 2016</xhtml:em>
            <xhtml:em> (or higher depending on your environment) from the list of available levels, and then click </xhtml:em>
            <xhtml:em>Raise</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Read the warning dialog and click </xhtml:em>
            <xhtml:em>OK</xhtml:em>* to confirm.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and raise the functional levels.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-ADFunctionalLevels.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-ADFunctionalLevels.ps1">Download Script: Audit-ADFunctionalLevels.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-ADFunctionalLevels.ps1
# Description: Audits the current domain and forest functional levels.

Import-Module ActiveDirectory

Write-Host "--- Auditing Active Directory Functional Levels ---" -ForegroundColor Cyan

$Domain = Get-ADDomain -ErrorAction SilentlyContinue
$Forest = Get-ADForest -ErrorAction SilentlyContinue

if ($Domain -and $Forest) {
    $DomainMode = $Domain.DomainMode
    $ForestMode = $Forest.ForestMode
    
    $MinDomainMode = [Microsoft.ActiveDirectory.Management.ADDomainMode]::Windows2016Domain
    $MinForestMode = [Microsoft.ActiveDirectory.Management.ADForestMode]::Windows2016Forest
    
    $DomainCompliant = [int]$DomainMode -ge [int]$MinDomainMode
    $ForestCompliant = [int]$ForestMode -ge [int]$MinForestMode
    
    if ($DomainCompliant) {
        Write-Host "Status: Domain Functional Level is compliant ($DomainMode)." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Domain Functional Level ($DomainMode) is below Windows Server 2016." -ForegroundColor Red
    }
    
    if ($ForestCompliant) {
        Write-Host "Status: Forest Functional Level is compliant ($ForestMode)." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Forest Functional Level ($ForestMode) is below Windows Server 2016." -ForegroundColor Red
    }
} else {
    Write-Host "VULNERABLE: Could not retrieve Active Directory settings. Run on a domain-joined machine with AD module installed." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Set-ADFunctionalLevels.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADFunctionalLevels.ps1">Download Script: Set-ADFunctionalLevels.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADFunctionalLevels.ps1
# Description: Raises Domain and Forest Functional Levels to Windows Server 2016.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Raise Functional Levels to Windows Server 2016..." -ForegroundColor Cyan

$Domain = Get-ADDomain -ErrorAction SilentlyContinue
$Forest = Get-ADForest -ErrorAction SilentlyContinue

if (-not $Domain -or -not $Forest) {
    Write-Error "Could not retrieve Active Directory settings. Run on a Domain Controller with administrative privileges."
    exit 1
}

# Raise Domain Functional Level
if ($Domain.DomainMode -lt [Microsoft.ActiveDirectory.Management.ADDomainMode]::Windows2016Domain) {
    try {
        Set-ADDomainMode -Identity $Domain.DNSRoot -DomainMode Windows2016Domain -Confirm:$false -ErrorAction Stop
        Write-Host "Domain Functional Level successfully raised to Windows Server 2016." -ForegroundColor Green
    } catch {
        Write-Error "Failed to raise Domain Functional Level. Error: $($_.Exception.Message)"
    }
} else {
    Write-Host "Domain Functional Level is already Windows Server 2016 or higher." -ForegroundColor Green
}

# Raise Forest Functional Level
if ($Forest.ForestMode -lt [Microsoft.ActiveDirectory.Management.ADForestMode]::Windows2016Forest) {
    try {
        Set-ADForestMode -Identity $Forest.Name -ForestMode Windows2016Forest -Confirm:$false -ErrorAction Stop
        Write-Host "Forest Functional Level successfully raised to Windows Server 2016." -ForegroundColor Green
    } catch {
        Write-Error "Failed to raise Forest Functional Level. Error: $($_.Exception.Message)"
    }
} else {
    Write-Host "Forest Functional Level is already Windows Server 2016 or higher." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADFunctionalLevels.ps1
# Description: Raises Domain and Forest Functional Levels to Windows Server 2016.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Raise Functional Levels to Windows Server 2016..." -ForegroundColor Cyan

$Domain = Get-ADDomain -ErrorAction SilentlyContinue
$Forest = Get-ADForest -ErrorAction SilentlyContinue

if (-not $Domain -or -not $Forest) {
    Write-Error "Could not retrieve Active Directory settings. Run on a Domain Controller with administrative privileges."
    exit 1
}

# Raise Domain Functional Level
if ($Domain.DomainMode -lt [Microsoft.ActiveDirectory.Management.ADDomainMode]::Windows2016Domain) {
    try {
        Set-ADDomainMode -Identity $Domain.DNSRoot -DomainMode Windows2016Domain -Confirm:$false -ErrorAction Stop
        Write-Host "Domain Functional Level successfully raised to Windows Server 2016." -ForegroundColor Green
    } catch {
        Write-Error "Failed to raise Domain Functional Level. Error: $($_.Exception.Message)"
    }
} else {
    Write-Host "Domain Functional Level is already Windows Server 2016 or higher." -ForegroundColor Green
}

# Raise Forest Functional Level
if ($Forest.ForestMode -lt [Microsoft.ActiveDirectory.Management.ADForestMode]::Windows2016Forest) {
    try {
        Set-ADForestMode -Identity $Forest.Name -ForestMode Windows2016Forest -Confirm:$false -ErrorAction Stop
        Write-Host "Forest Functional Level successfully raised to Windows Server 2016." -ForegroundColor Green
    } catch {
        Write-Error "Failed to raise Forest Functional Level. Error: $($_.Exception.Message)"
    }
} else {
    Write-Host "Forest Functional Level is already Windows Server 2016 or higher." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-005] Default Domain and Domain Controllers Policies Management</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers and Domain Members (Forest-wide)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/default-policies-recommendations.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modifying the Default Domain Policy (DDP) and Default Domain Controllers Policy (DDCP) introduces significant operational risks. These default policies define the core directory baseline configurations required for Active Directory to initialize, replicate, and authenticate.</xhtml:p>
        <xhtml:p>However, a critical exception to modular Group Policy design applies to <xhtml:strong>Account Policies</xhtml:strong> (Password, Account Lockout, and Kerberos settings) and <xhtml:strong>Encrypting File System (EFS)</xhtml:strong> policies. Windows operating systems only process domain-wide Account Policies from the GPO linked directly to the domain root (by default, the Default Domain Policy). Custom GPOs linked at lower levels containing these settings will be ignored for domain accounts. Therefore, these specific baselines must be configured directly within the Default Domain Policy itself.</xhtml:p>
        <xhtml:p>All other custom hardening settings (such as local User Rights Assignments, Audit Policies, and registry parameters) should be managed via dedicated modular GPOs (e.g., <xhtml:code>SEC_DomainControllers_Hardening</xhtml:code>) linked at higher precedence.</xhtml:p>
        <xhtml:p>Integrating the following controls inside the DDP/DDCP and custom GPOs completes the Active Directory management baseline: 1. <xhtml:strong>Disabling Encrypting File System (EFS)</xhtml:strong>: EFS allows users to encrypt files on local drives. This makes files difficult to recover or back up securely. Enterprise environments should enforce full-disk encryption (BitLocker) rather than user-managed file-level encryption. Disabling EFS prevents unauthorized user-level encryption. 2. <xhtml:strong>Enforcing Group Policy Background Refresh</xhtml:strong>: Ensuring that Group Policy background refresh is active prevents unauthorized local overrides from persisting. Setting the policy <xhtml:code>Turn off background refresh of Group Policy</xhtml:code> to <xhtml:strong>Disabled</xhtml:strong> ensures that GPOs are reapplied every 90 minutes. 3. <xhtml:strong>Mandating GPO Comments</xhtml:strong>: Documenting the purpose, author, and revision history in the GPO comments field ensures accountability and prevents configuration drift. 4. <xhtml:strong>Restricting gpupdate /force Overuse</xhtml:strong>: Running <xhtml:code>gpupdate /force</xhtml:code> causes endpoints and servers to re-download all applied GPOs from Domain Controllers. In large environments, this can trigger severe network congestion and CPU spikes on DCs. Administrators should use standard <xhtml:code>gpupdate</xhtml:code> without the <xhtml:code>/force</xhtml:code> switch unless a full re-application of unchanged policies is required.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Management Console (GPMC) (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Configure Default Domain Policy for Account and EFS Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Log on to a management workstation or Domain Controller with <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Right-click the <xhtml:strong>Default Domain Policy</xhtml:strong> and select <xhtml:strong>Edit</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Policies</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Encrypting File System</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the <xhtml:strong>General</xhtml:strong> tab, under <xhtml:strong>File encryption using Encrypting File System (EFS)</xhtml:strong>, select <xhtml:strong>Disabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to the Account Policies node to configure domain-wide Password and Lockout parameters as detailed in <xhtml:a href="../08-endpoints/configure-account-policies.md">configure-account-policies.md</xhtml:a>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Establish Modular GPOs for Non-Account Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the <xhtml:code>gpmc.msc</xhtml:code> console tree, right-click <xhtml:strong>Group Policy Objects</xhtml:strong> and select <xhtml:strong>New</xhtml:strong>.</xhtml:li>
          <xhtml:li>Name the GPO <xhtml:code>SEC_DomainControllers_Hardening</xhtml:code> (and <xhtml:code>SEC_Domain_Hardening</xhtml:code> for domain members) and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Right-click the <xhtml:strong>Domain Controllers</xhtml:strong> OU (or root domain) and select <xhtml:strong>Link an Existing GPO</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:code>SEC_DomainControllers_Hardening</xhtml:code> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Domain Controllers</xhtml:strong> OU in the left pane, navigate to the <xhtml:strong>Linked Group Policy Objects</xhtml:strong> tab, select the custom hardening GPO, and use the green up arrow to set its <xhtml:strong>Link Order</xhtml:strong> to <xhtml:strong>1</xhtml:strong> (highest precedence).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Configure Group Policy Background Refresh</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Edit your modular hardening GPO (e.g., <xhtml:code>SEC_DomainControllers_Hardening</xhtml:code> or <xhtml:code>SEC_Domain_Hardening</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Group Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click the policy <xhtml:strong>Turn off background refresh of Group Policy</xhtml:strong> and set it to <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 4: Mandate GPO Comments for Accountability</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In GPMC, right-click your GPO, select <xhtml:strong>Properties</xhtml:strong>, and navigate to the <xhtml:strong>Comment</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Enter a structured comment containing:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Purpose</xhtml:em>*: [Brief explanation of GPO controls]</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Author</xhtml:em>*: [Administrator Name or Security Team]</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Date</xhtml:em>*: [Creation/Modification Date]</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Reference Requirement</xhtml:em>*: [e.g., REQ-ARCH-005]</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and set up the GPO structure, EFS, and background refresh locally.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-GPOPrecedence.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-GPOPrecedence.ps1">Download Script: Audit-GPOPrecedence.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-GPOPrecedence.ps1
# Description: Verifies GPO precedence on DC OU, and checks local EFS and background refresh registry configuration.

Import-Module ActiveDirectory
Import-Module GroupPolicy

Write-Host "--- Auditing Default Policies and Precedence ---" -ForegroundColor Cyan

# 1. Audit GPO Precedence on Domain Controllers OU
$DomainInfo = Get-ADDomain
$DCOUDN = "OU=Domain Controllers,$($DomainInfo.DistinguishedName)"

try {
    $OUInfo = Get-GPInheritance -Target $DCOUDN -ErrorAction Stop
    
    Write-Host "`nLinked GPOs on Domain Controllers OU:" -ForegroundColor Yellow
    $HardeningGPOFound = $false
    $HardeningOrder = 999
    $DefaultDCOrder = 999
    
    foreach ($link in $OUInfo.GpoLinks) {
        $status = if ($link.Enabled) { "Enabled" } else { "Disabled" }
        Write-Host "    - Link Order: $($link.Order) | GPO Name: $($link.DisplayName) | Status: $status" -ForegroundColor White
        
        if ($link.DisplayName -like "*Hardening*" -and $link.Enabled) {
            $HardeningGPOFound = $true
            $HardeningOrder = $link.Order
        }
        if ($link.DisplayName -eq "Default Domain Controllers Policy") {
            $DefaultDCOrder = $link.Order
        }
    }
    
    if ($HardeningGPOFound -and $HardeningOrder -lt $DefaultDCOrder) {
        Write-Host "`n[+] GPO Precedence: Compliant. Custom hardening GPO has higher precedence (Order $HardeningOrder) than Default DC Policy (Order $DefaultDCOrder)." -ForegroundColor Green
    } else {
        Write-Host "`n[!] VULNERABLE: No active dedicated hardening GPO found with higher precedence than Default DC Policy." -ForegroundColor Red
    }
} catch {
    Write-Host "[!] Could not retrieve GPO information for DC OU. Error: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Audit EFS Registry status
$EfsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\EFS"
$EfsVal = Get-ItemProperty -Path $EfsPath -Name "EfsConfiguration" -ErrorAction SilentlyContinue
if ($EfsVal -and $EfsVal.EfsConfiguration -eq 1) {
    Write-Host "[+] EFS Configuration: Secure (Disabled)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: EFS is not disabled in registry policies." -ForegroundColor Red
}

# 3. Audit Background Refresh status
$SysPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$BkgVal = Get-ItemProperty -Path $SysPath -Name "DisableBkGndGroupPolicy" -ErrorAction SilentlyContinue
if ($BkgVal -and $BkgVal.DisableBkGndGroupPolicy -eq 0) {
    Write-Host "[+] Group Policy Background Refresh: Secure (Active)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Group Policy background refresh is turned off in registry." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Set-ADModularGPO.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADModularGPO.ps1">Download Script: Set-ADModularGPO.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADModularGPO.ps1
# Description: Creates DC hardening GPO with top precedence, disables EFS, and enables background refresh locally.

Import-Module ActiveDirectory
Import-Module GroupPolicy

Write-Host "Applying Default Policies hardening baseline..." -ForegroundColor Cyan

# 1. Create and Link DC Hardening GPO
$DomainInfo = Get-ADDomain
$DCOUDN = "OU=Domain Controllers,$($DomainInfo.DistinguishedName)"
$GPOName = "SEC_DomainControllers_Hardening"

try {
    $GPO = Get-GPO -Name $GPOName -ErrorAction SilentlyContinue
    if (-not $GPO) {
        $GPO = New-GPO -Name $GPOName -Comment "Dedicated GPO for Domain Controllers hardening. Requirements: REQ-ARCH-005." -ErrorAction Stop
        Write-Host "[+] GPO '$GPOName' created successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] GPO '$GPOName' already exists." -ForegroundColor Yellow
    }
    
    $Links = (Get-GPInheritance -Target $DCOUDN).GpoLinks
    $IsLinked = $false
    foreach ($link in $Links) {
        if ($link.DisplayName -eq $GPOName) {
            $IsLinked = $true
            break
        }
    }
    
    if (-not $IsLinked) {
        New-GPLink -Name $GPOName -Target $DCOUDN -LinkEnabled Yes -ErrorAction Stop | Out-Null
        Write-Host "[+] GPO '$GPOName' linked to Domain Controllers OU." -ForegroundColor Green
    } else {
        Write-Host "[+] GPO '$GPOName' is already linked to Domain Controllers OU." -ForegroundColor Yellow
    }
    
    Set-GPLink -Name $GPOName -Target $DCOUDN -Order 1 -ErrorAction Stop | Out-Null
    Write-Host "[+] GPO '$GPOName' set to link order 1 (highest precedence)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure GPO structure. Error: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Local Registry for EFS (Disable)
$EfsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\EFS"
if (-not (Test-Path $EfsPath)) {
    New-Item -Path $EfsPath -Force | Out-Null
}
Set-ItemProperty -Path $EfsPath -Name "EfsConfiguration" -Value 1 -Type DWord -Force
Write-Host "[+] EFS registry policy configured to Disabled." -ForegroundColor Green

# 3. Configure Local Registry for GP Background Refresh (Active)
$SysPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SysPath)) {
    New-Item -Path $SysPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPath -Name "DisableBkGndGroupPolicy" -Value 0 -Type DWord -Force
Write-Host "[+] Group Policy background refresh registry policy enabled." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADModularGPO.ps1
# Description: Creates DC hardening GPO with top precedence, disables EFS, and enables background refresh locally.

Import-Module ActiveDirectory
Import-Module GroupPolicy

Write-Host "Applying Default Policies hardening baseline..." -ForegroundColor Cyan

# 1. Create and Link DC Hardening GPO
$DomainInfo = Get-ADDomain
$DCOUDN = "OU=Domain Controllers,$($DomainInfo.DistinguishedName)"
$GPOName = "SEC_DomainControllers_Hardening"

try {
    $GPO = Get-GPO -Name $GPOName -ErrorAction SilentlyContinue
    if (-not $GPO) {
        $GPO = New-GPO -Name $GPOName -Comment "Dedicated GPO for Domain Controllers hardening. Requirements: REQ-ARCH-005." -ErrorAction Stop
        Write-Host "[+] GPO '$GPOName' created successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] GPO '$GPOName' already exists." -ForegroundColor Yellow
    }
    
    $Links = (Get-GPInheritance -Target $DCOUDN).GpoLinks
    $IsLinked = $false
    foreach ($link in $Links) {
        if ($link.DisplayName -eq $GPOName) {
            $IsLinked = $true
            break
        }
    }
    
    if (-not $IsLinked) {
        New-GPLink -Name $GPOName -Target $DCOUDN -LinkEnabled Yes -ErrorAction Stop | Out-Null
        Write-Host "[+] GPO '$GPOName' linked to Domain Controllers OU." -ForegroundColor Green
    } else {
        Write-Host "[+] GPO '$GPOName' is already linked to Domain Controllers OU." -ForegroundColor Yellow
    }
    
    Set-GPLink -Name $GPOName -Target $DCOUDN -Order 1 -ErrorAction Stop | Out-Null
    Write-Host "[+] GPO '$GPOName' set to link order 1 (highest precedence)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure GPO structure. Error: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Local Registry for EFS (Disable)
$EfsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\EFS"
if (-not (Test-Path $EfsPath)) {
    New-Item -Path $EfsPath -Force | Out-Null
}
Set-ItemProperty -Path $EfsPath -Name "EfsConfiguration" -Value 1 -Type DWord -Force
Write-Host "[+] EFS registry policy configured to Disabled." -ForegroundColor Green

# 3. Configure Local Registry for GP Background Refresh (Active)
$SysPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SysPath)) {
    New-Item -Path $SysPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPath -Name "DisableBkGndGroupPolicy" -Value 0 -Type DWord -Force
Write-Host "[+] Group Policy background refresh registry policy enabled." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-006] Harden Active Directory Domain Trusts</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/harden-domain-trusts.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory trust relationships permit authentication and resource access across domain or forest boundaries. However, weak trust configurations can serve as transit routes for attackers to compromise trusting domains.</xhtml:p>
        <xhtml:p>Specifically: 1. <xhtml:strong>SID History</xhtml:strong>: Enabling SID History allows users from a trusted forest to present security identifiers (SIDs) from other domains, bypass SID filtering, and potentially impersonate high-privilege administrators in the trusting forest. Disabling SID History on external/forest trusts prevents this path of escalation. 2. <xhtml:strong>SID Filtering / Quarantine</xhtml:strong>: Enabling Quarantine (SID Filtering) on external trusts ensures that the trusting domain filters out unauthorized SIDs presented in authorization packets, restricting access only to SIDs originating from the trusted domain itself. 3. <xhtml:strong>Kerberos TGT Delegation</xhtml:strong>: If TGT delegation is allowed on inbound trusts, a user authenticating from the trusted forest to a service in the trusting domain can have their Kerberos Ticket Granting Ticket (TGT) delegated to that service. If that service or host is compromised, the attacker can harvest the user's TGT and impersonate them. Blocking TGT delegation is critical to prevent credential exposure. 4. <xhtml:strong>Selective Authentication</xhtml:strong>: Enforcing selective authentication restricts cross-forest access, allowing administrators to explicitly define which users/groups from the trusted forest can authenticate to specific resources in the trusting forest.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Domains and Trusts GUI Configuration</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Domains and Trusts</xhtml:strong> (<xhtml:code>domain.msc</xhtml:code>) on a Domain Controller.</xhtml:li>
          <xhtml:li>Right-click the trusting domain and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Trusts</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Under either <xhtml:strong>Domains that trust this domain (Inbound)</xhtml:strong> or <xhtml:strong>Domains trusted by this domain (Outbound)</xhtml:strong>, select the target trust and click <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure selective authentication:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select the </xhtml:em>
            <xhtml:em>Authentication</xhtml:em>* tab.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Change the option from </xhtml:em>
            <xhtml:em>Forest-wide authentication</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>Selective authentication</xhtml:em>*.</xhtml:li>
          <xhtml:li>Enforce SID filtering and quarantine rules (usually performed automatically when establishing external trusts).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; netdom Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to audit and harden trust relationships. The <xhtml:code>netdom</xhtml:code> utility is used to query and apply the trust settings.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADTrustHardening.ps1">Download Script: Set-ADTrustHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADTrustHardening.ps1
# Description: Hardens trust relationships by disabling SID History and TGT Delegation, and enabling Quarantine.

Write-Host "Applying hardening requirement: Harden Active Directory Domain Trusts..." -ForegroundColor Cyan

# Set target trust variables (replace with your domain names)
$TrustingDomain = "corp.local"
$TrustedDomain = "partner.local"

# 1. Disable SID History on Forest/External Trust
Write-Host "Disabling SID History on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /EnableSIDHistory:no

# 2. Enable Quarantine (SID Filtering) on External Domain Trust
Write-Host "Enabling Quarantine on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /Quarantine:yes

# 3. Disable TGT Delegation over Inbound Trust
Write-Host "Disabling Kerberos TGT Delegation on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /EnableTGTDelegation:no

Write-Host "Trust hardening commands executed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the trust configuration state:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-ADTrustStatus.ps1">Download Script: Get-ADTrustStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-ADTrustStatus.ps1
# Description: Audits trust attributes and configuration settings.

Import-Module ActiveDirectory

Write-Host "--- Auditing Trust Relationships ---" -ForegroundColor Cyan

$Trusts = Get-ADTrust -Filter * -Properties *

if ($Trusts) {
    foreach ($Trust in $Trusts) {
        Write-Host "[+] Trust Name: $($Trust.Name)" -ForegroundColor Green
        Write-Host "    - Trust Type: $($Trust.TrustType)" -ForegroundColor White
        Write-Host "    - Direction: $($Trust.TrustDirection)" -ForegroundColor White
        Write-Host "    - Selective Authentication: $($Trust.SelectiveAuthentication)" -ForegroundColor White
        Write-Host "    - Disallow Transitivity: $($Trust.DisallowTransitivity)" -ForegroundColor White
        
        # Verify specific settings using netdom query
        Write-Host "    - netdom Configuration Details:" -ForegroundColor White
        netdom trust $Trust.Source /domain:$Trust.Target /Query
    }
} else {
    Write-Host "[-] No trust relationships found in the domain." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADTrustHardening.ps1
# Description: Hardens trust relationships by disabling SID History and TGT Delegation, and enabling Quarantine.

Write-Host "Applying hardening requirement: Harden Active Directory Domain Trusts..." -ForegroundColor Cyan

# Set target trust variables (replace with your domain names)
$TrustingDomain = "corp.local"
$TrustedDomain = "partner.local"

# 1. Disable SID History on Forest/External Trust
Write-Host "Disabling SID History on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /EnableSIDHistory:no

# 2. Enable Quarantine (SID Filtering) on External Domain Trust
Write-Host "Enabling Quarantine on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /Quarantine:yes

# 3. Disable TGT Delegation over Inbound Trust
Write-Host "Disabling Kerberos TGT Delegation on trust from $($TrustingDomain) to $($TrustedDomain)..." -ForegroundColor White
netdom trust $TrustingDomain /domain:$TrustedDomain /EnableTGTDelegation:no

Write-Host "Trust hardening commands executed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ARCH-007" severity="high" weight="10.0" selected="false">
      <title>[REQ-ARCH-007] Harden Microsoft Exchange Active Directory Permissions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Controllers and Domain Root Object (Tier 0).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Active Directory Domain Services (All supported functional levels).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>01-architecture/harden-exchange-permissions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>By default, installing Microsoft Exchange Server in an Active Directory forest modifies the permissions of the domain root object. It grants the <xhtml:strong>Exchange Windows Permissions</xhtml:strong> group (and sometimes <xhtml:strong>Exchange Servers</xhtml:strong>) write permissions (<xhtml:code>WriteDacl</xhtml:code> and <xhtml:code>WriteOwner</xhtml:code>) over the domain root container.</xhtml:p>
        <xhtml:p>This configuration presents a critical security risk: 1. <xhtml:strong>Privilege Escalation</xhtml:strong>: Any user or service account with administrative control over Exchange, or any compromised Exchange server itself, can write new permissions to the domain root. 2. <xhtml:strong>DCSync Exploitation</xhtml:strong>: The attacker can grant their own account the <xhtml:code>ds-Replication-Get-Changes</xhtml:code> and <xhtml:code>ds-Replication-Get-Changes-All</xhtml:code> (DCSync) extended rights. This allows the attacker to dump password hashes directly from the domain controller database (NTDS.dit), leading to a complete forest compromise.</xhtml:p>
        <xhtml:p>Restricting these write permissions ensures that Exchange servers cannot modify domain-level security descriptors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users &amp; Computers (GUI Configuration)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>) on a management console with Domain Admin privileges.</xhtml:li>
          <xhtml:li>Enable <xhtml:strong>Advanced Features</xhtml:strong> under the <xhtml:strong>View</xhtml:strong> menu.</xhtml:li>
          <xhtml:li>Right-click the root domain object (e.g., <xhtml:code>domain.local</xhtml:code>) and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Security</xhtml:strong> tab, then click <xhtml:strong>Advanced</xhtml:strong>.</xhtml:li>
          <xhtml:li>Locate the permission entries for <xhtml:strong>Exchange Windows Permissions</xhtml:strong> and <xhtml:strong>Exchange Servers</xhtml:strong>.</xhtml:li>
          <xhtml:li>Review the permissions:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Remove any entries granting </xhtml:em>
            <xhtml:em>Modify permissions</xhtml:em>
            <xhtml:em> (`WriteDacl`) or </xhtml:em>
            <xhtml:em>Modify owner</xhtml:em>* (<xhtml:code>WriteOwner</xhtml:code>) on the domain root.</xhtml:li>
          <xhtml:li>* Ensure standard read and object creation permissions (such as writing specific user properties for mailbox management) remain unchanged.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Active Directory Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>To automate verification and remediation of the domain root ACL:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Harden-ExchangePermissions.ps1">Download Script: Harden-ExchangePermissions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Harden-ExchangePermissions.ps1
# Description: Removes WriteDacl and WriteOwner permissions for Exchange groups on the domain root.

Import-Module ActiveDirectory

$DomainDN = (Get-ADDomain).DistinguishedName
$DomainPath = "AD:\$DomainDN"

# Retrieve existing ACL
$Acl = Get-Acl -Path $DomainPath
$DangerousAcesToRemove = @()

# Define Exchange groups to target
$TargetGroups = @("Exchange Windows Permissions", "Exchange Servers")
$TargetSids = @()

foreach ($groupName in $TargetGroups) {
    try {
        $sid = (Get-ADGroup -Identity $groupName).SID.Value
        $TargetSids += $sid
    }
    catch {
        Write-Host "Group '$groupName' not found in this domain. Skipping." -ForegroundColor Yellow
    }
}

if ($TargetSids.Count -eq- 0) {
    Write-Host "No Exchange groups detected. No permissions to harden." -ForegroundColor Green
    exit 0
}

# Scan ACL for dangerous ACEs
foreach ($ace in $Acl.Access) {
    $identity = $ace.IdentityReference
    try {
        $sid = $identity.Translate([System.Security.Principal.SecurityIdentifier]).Value
    }
    catch {
        continue
    }

    if ($TargetSids -contains $sid) {
        # Check for WriteDacl or WriteOwner rights
        $hasWriteDacl = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl
        $hasWriteOwner = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner

        if ($hasWriteDacl -or $hasWriteOwner) {
            $DangerousAcesToRemove += $ace
        }
    }
}

if ($DangerousAcesToRemove.Count -eq 0) {
    Write-Host "[+] Domain root ACL is compliant. No dangerous Exchange write permissions found." -ForegroundColor Green
} else {
    Write-Host "[-] Found $($DangerousAcesToRemove.Count) dangerous Exchange permissions. Removing..." -ForegroundColor Yellow
    foreach ($ace in $DangerousAcesToRemove) {
        $Acl.RemoveAccessRule($ace) | Out-Null
    }
    Set-Acl -Path $DomainPath -AclObject $Acl
    Write-Host "[+] Successfully removed dangerous Exchange WriteDacl/WriteOwner permissions from domain root." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the domain root permissions:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-ExchangePermissionsStatus.ps1">Download Script: Get-ExchangePermissionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-ExchangePermissionsStatus.ps1
# Check if Exchange groups hold WriteDacl/WriteOwner permissions on the domain root.

Import-Module ActiveDirectory

$DomainDN = (Get-ADDomain).DistinguishedName
$DomainPath = "AD:\$DomainDN"

$Acl = Get-Acl -Path $DomainPath
$TargetGroups = @("Exchange Windows Permissions", "Exchange Servers")
$TargetSids = @()

foreach ($groupName in $TargetGroups) {
    try {
        $sid = (Get-ADGroup -Identity $groupName).SID.Value
        $TargetSids += $sid
    }
    catch {
        Write-Verbose "Group '$groupName' not found in Active Directory."
    }
}

if ($TargetSids.Count -eq 0) {
    Write-Host "[+] COMPLIANT: Exchange groups are not present in this domain."
    exit 0
}

$nonCompliantAces = 0

foreach ($ace in $Acl.Access) {
    $identity = $ace.IdentityReference
    try {
        $sid = $identity.Translate([System.Security.Principal.SecurityIdentifier]).Value
    }
    catch {
        continue
    }

    if ($TargetSids -contains $sid) {
        $hasWriteDacl = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl
        $hasWriteOwner = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner

        if ($hasWriteDacl -or $hasWriteOwner) {
            Write-Host "[!] NON-COMPLIANT: Group '$($identity.Value)' has permissions: $($ace.ActiveDirectoryRights)" -ForegroundColor Red
            $nonCompliantAces++
        }
    }
}

if ($nonCompliantAces -eq 0) {
    Write-Host "[+] COMPLIANT: No Exchange groups have WriteDacl or WriteOwner permissions on the domain root." -ForegroundColor Green
    exit 0
} else {
    Write-Host "[!] NON-COMPLIANT: Dangerous Exchange write permissions detected on the domain root." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Harden-ExchangePermissions.ps1
# Description: Removes WriteDacl and WriteOwner permissions for Exchange groups on the domain root.

Import-Module ActiveDirectory

$DomainDN = (Get-ADDomain).DistinguishedName
$DomainPath = "AD:\$DomainDN"

# Retrieve existing ACL
$Acl = Get-Acl -Path $DomainPath
$DangerousAcesToRemove = @()

# Define Exchange groups to target
$TargetGroups = @("Exchange Windows Permissions", "Exchange Servers")
$TargetSids = @()

foreach ($groupName in $TargetGroups) {
    try {
        $sid = (Get-ADGroup -Identity $groupName).SID.Value
        $TargetSids += $sid
    }
    catch {
        Write-Host "Group '$groupName' not found in this domain. Skipping." -ForegroundColor Yellow
    }
}

if ($TargetSids.Count -eq- 0) {
    Write-Host "No Exchange groups detected. No permissions to harden." -ForegroundColor Green
    exit 0
}

# Scan ACL for dangerous ACEs
foreach ($ace in $Acl.Access) {
    $identity = $ace.IdentityReference
    try {
        $sid = $identity.Translate([System.Security.Principal.SecurityIdentifier]).Value
    }
    catch {
        continue
    }

    if ($TargetSids -contains $sid) {
        # Check for WriteDacl or WriteOwner rights
        $hasWriteDacl = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl
        $hasWriteOwner = ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner) -eq [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner

        if ($hasWriteDacl -or $hasWriteOwner) {
            $DangerousAcesToRemove += $ace
        }
    }
}

if ($DangerousAcesToRemove.Count -eq 0) {
    Write-Host "[+] Domain root ACL is compliant. No dangerous Exchange write permissions found." -ForegroundColor Green
} else {
    Write-Host "[-] Found $($DangerousAcesToRemove.Count) dangerous Exchange permissions. Removing..." -ForegroundColor Yellow
    foreach ($ace in $DangerousAcesToRemove) {
        $Acl.RemoveAccessRule($ace) | Out-Null
    }
    Set-Acl -Path $DomainPath -AclObject $Acl
    Write-Host "[+] Successfully removed dangerous Exchange WriteDacl/WriteOwner permissions from domain root." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:1007" />
      </check>
    </Rule>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening">
    <title>Module 2: Domain Controller Hardening</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-001] Disable SMBv1</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-smbv1.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>SMBv1 (Server Message Block version 1) is a legacy networking protocol designed over 30 years ago. It lacks modern security features such as packet encryption, cryptographic signing enforcement, and robust integrity verification.</xhtml:p>
        <xhtml:p>SMBv1 contains severe remote code execution (RCE) vulnerabilities (e.g., the EternalBlue vulnerability mitigated in MS17-010). Attackers can exploit SMBv1 to execute commands remotely, capture credentials, or perform lateral movement across the domain network. Domain Controllers (Tier 0) are highly sensitive targets, and keeping SMBv1 enabled presents an unacceptable risk. Disabling both the server protocol and the client driver eliminates this entire attack surface.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Configure Group Policy Preferences to enforce the registry settings:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new Registry Preference to disable the SMBv1 Server (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>SMB1</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second Registry Preference to disable the SMBv1 Client Driver (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\mrxsmb10</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally or if the control is not manageable via standard GPO GUI interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableSMBv1.ps1">Download Script: Configure-DisableSMBv1.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableSMBv1.ps1
# Description: Disables SMBv1 server protocol and mrxsmb10 client driver.

Write-Host "Applying hardening requirement: Disable SMBv1..." -ForegroundColor Cyan

# 1. Disable SMBv1 Server
$srvRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $srvRegPath)) {
    New-Item -Path $srvRegPath -Force | Out-Null
}
Set-ItemProperty -Path $srvRegPath -Name "SMB1" -Value 0 -Type DWord
Write-Host "SMBv1 Server registry configuration applied." -ForegroundColor Green

# Use standard cmdlet if available
if (Get-Command -Name Set-SmbServerConfiguration -ErrorAction SilentlyContinue) {
    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
    Write-Host "SMBv1 Server protocol disabled via cmdlet." -ForegroundColor Green
}

# 2. Disable SMBv1 Client Driver
$clientRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10"
if (Test-Path $clientRegPath) {
    Set-ItemProperty -Path $clientRegPath -Name "Start" -Value 4 -Type DWord
    Write-Host "SMBv1 Client mrxsmb10 driver disabled." -ForegroundColor Green
} else {
    Write-Host "mrxsmb10 driver registry key not found (may already be removed)." -ForegroundColor Yellow
}

Write-Host "Hardening applied successfully. A system reboot is required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-SMBv1Status.ps1">Download Script: Get-SMBv1Status.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SMBv1Status.ps1
# Description: Audits the registry configuration of SMBv1 server and client components.

Write-Host "--- Auditing SMBv1 Configuration ---" -ForegroundColor Cyan
$vulnerable = $false

# Check Server configuration
if (Get-Command -Name Get-SmbServerConfiguration -ErrorAction SilentlyContinue) {
    $smbConfig = Get-SmbServerConfiguration
    if ($smbConfig.EnableSMB1Protocol -eq $true) {
        Write-Host "[!] VULNERABLE: SMBv1 Server protocol is enabled via configuration." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] SMBv1 Server protocol is disabled." -ForegroundColor Green
    }
} else {
    $srvReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "SMB1" -ErrorAction SilentlyContinue
    if ($srvReg -and $srvReg.SMB1 -eq 1) {
        Write-Host "[!] VULNERABLE: SMB1 registry parameter is set to 1 (Enabled)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] SMB1 registry parameter is disabled or not present." -ForegroundColor Green
    }
}

# Check Client configuration
$driverReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10" -Name "Start" -ErrorAction SilentlyContinue
if ($driverReg -and $driverReg.Start -ne 4) {
    Write-Host "[!] VULNERABLE: mrxsmb10 client driver is not disabled (Start value: $($driverReg.Start))." -ForegroundColor Red
    $vulnerable = $true
} else {
    Write-Host "[+] mrxsmb10 client driver is disabled." -ForegroundColor Green
}

if ($vulnerable) {
    Write-Host "Audit result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSMBv1.ps1
# Description: Disables SMBv1 server protocol and mrxsmb10 client driver.

Write-Host "Applying hardening requirement: Disable SMBv1..." -ForegroundColor Cyan

# 1. Disable SMBv1 Server
$srvRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $srvRegPath)) {
    New-Item -Path $srvRegPath -Force | Out-Null
}
Set-ItemProperty -Path $srvRegPath -Name "SMB1" -Value 0 -Type DWord
Write-Host "SMBv1 Server registry configuration applied." -ForegroundColor Green

# Use standard cmdlet if available
if (Get-Command -Name Set-SmbServerConfiguration -ErrorAction SilentlyContinue) {
    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
    Write-Host "SMBv1 Server protocol disabled via cmdlet." -ForegroundColor Green
}

# 2. Disable SMBv1 Client Driver
$clientRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10"
if (Test-Path $clientRegPath) {
    Set-ItemProperty -Path $clientRegPath -Name "Start" -Value 4 -Type DWord
    Write-Host "SMBv1 Client mrxsmb10 driver disabled." -ForegroundColor Green
} else {
    Write-Host "mrxsmb10 driver registry key not found (may already be removed)." -ForegroundColor Yellow
}

Write-Host "Hardening applied successfully. A system reboot is required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-002] Disable Multicast Name Resolution</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-multicast-name-resolution.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Link-Local Multicast Name Resolution (LLMNR), NetBIOS Name Service (NBT-NS), and multicast DNS (mDNS) are fallback name resolution protocols. When a Windows host is unable to resolve a name via standard DNS, it broadcasts the query to the local subnet using these protocols.</xhtml:p>
        <xhtml:p>Adversaries on the same subnet can easily sniff these broadcast/multicast queries and respond with their own IP address (using tools such as Responder). When the requesting client attempts to authenticate to the fake host, its NTLM credentials (specifically NTLMv2 hashes) are captured by the attacker. These hashes can then be cracked offline or relayed to other hosts on the network (e.g., Active Directory Certificate Services or SMB servers) to achieve unauthorized administrative access. Disabling these legacy fallback protocols eliminates these name resolution spoofing attack vectors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Configure Group Policy to disable LLMNR, and Group Policy Preferences to disable NetBIOS and mDNS:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\DNS Client</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn off multicast name resolution</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure NetBIOS settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled: Disable NetBIOS name resolution on public networks</xhtml:code> (Note: Requires newer Windows 11 / Server 2022 ADMX templates)</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a Registry Preference to disable mDNS (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Dnscache\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>EnableMDNS</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>For NetBIOS, because adapter GUIDs vary, Group Policy Preferences can be configured with target registry keys, but NetBIOS disabling is often handled dynamically via DHCP scope options (Option 046 or by setting NetBIOS options via DHCP) or locally via scripting on server endpoints. Alternatively, create Registry Preferences for common interfaces or apply Option B locally.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the settings locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableMulticastNameResolution.ps1">Download Script: Configure-DisableMulticastNameResolution.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableMulticastNameResolution.ps1
# Description: Disables LLMNR, NetBIOS over TCP/IP, and mDNS on all interfaces.

Write-Host "Applying hardening requirement: Disable Multicast Name Resolution..." -ForegroundColor Cyan

# 1. Disable LLMNR
$llmnrPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
if (-not (Test-Path $llmnrPath)) {
    New-Item -Path $llmnrPath -Force | Out-Null
}
Set-ItemProperty -Path $llmnrPath -Name "EnableMulticast" -Value 0 -Type DWord
Write-Host "LLMNR disabled via registry policy." -ForegroundColor Green

# 2. Disable mDNS
$mdnsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
if (-not (Test-Path $mdnsPath)) {
    New-Item -Path $mdnsPath -Force | Out-Null
}
Set-ItemProperty -Path $mdnsPath -Name "EnableMDNS" -Value 0 -Type DWord
Write-Host "mDNS disabled via registry." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all Network Adapters
$interfacesPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces"
if (Test-Path $interfacesPath) {
    $interfaces = Get-ChildItem -Path $interfacesPath
    foreach ($interface in $interfaces) {
        $intName = $interface.PSChildName
        $intPath = "$($interfacesPath)\$($intName)"
        Set-ItemProperty -Path $intPath -Name "NetbiosOptions" -Value 2 -Type DWord
        Write-Host "  NetBIOS disabled on interface: $($intName)" -ForegroundColor Gray
    }
    Write-Host "NetBIOS over TCP/IP disabled on all active interfaces." -ForegroundColor Green
} else {
    Write-Host "NetBIOS interfaces registry path not found." -ForegroundColor Yellow
}

Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-MulticastNameResolutionStatus.ps1">Download Script: Get-MulticastNameResolutionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-MulticastNameResolutionStatus.ps1
# Description: Audits LLMNR, NetBIOS, and mDNS registry settings.

Write-Host "--- Auditing Multicast Name Resolution ---" -ForegroundColor Cyan
$vulnerable = $false

# 1. Audit LLMNR
$llmnrReg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Name "EnableMulticast" -ErrorAction SilentlyContinue
if ($llmnrReg) {
    if ($llmnrReg.EnableMulticast -eq 1) {
        Write-Host "[!] VULNERABLE: LLMNR is explicitly enabled." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] LLMNR is disabled." -ForegroundColor Green
    }
} else {
    Write-Host "[!] VULNERABLE: LLMNR policy key 'EnableMulticast' does not exist (default is enabled)." -ForegroundColor Red
    $vulnerable = $true
}

# 2. Audit mDNS
$mdnsReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters" -Name "EnableMDNS" -ErrorAction SilentlyContinue
if ($mdnsReg) {
    if ($mdnsReg.EnableMDNS -ne 0) {
        Write-Host "[!] VULNERABLE: mDNS is enabled." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] mDNS is disabled." -ForegroundColor Green
    }
} else {
    # Default is enabled on Windows Server 2022 / Windows 11
    Write-Host "[!] VULNERABLE: mDNS key 'EnableMDNS' is missing (default is enabled)." -ForegroundColor Red
    $vulnerable = $true
}

# 3. Audit NetBIOS over TCP/IP
$interfacesPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces"
if (Test-Path $interfacesPath) {
    $interfaces = Get-ChildItem -Path $interfacesPath
    $netbiosEnabledCount = 0
    foreach ($interface in $interfaces) {
        $intName = $interface.PSChildName
        $intPath = "$($interfacesPath)\$($intName)"
        $optVal = Get-ItemProperty -Path $intPath -Name "NetbiosOptions" -ErrorAction SilentlyContinue
        if ($optVal) {
            if ($optVal.NetbiosOptions -ne 2) {
                Write-Host "[!] VULNERABLE: NetBIOS is enabled/default on interface: $($intName) (NetbiosOptions = $($optVal.NetbiosOptions))" -ForegroundColor Red
                $netbiosEnabledCount = $netbiosEnabledCount + 1
            }
        } else {
            Write-Host "[!] VULNERABLE: NetbiosOptions value missing (default enabled) on interface: $($intName)" -ForegroundColor Red
            $netbiosEnabledCount = $netbiosEnabledCount + 1
        }
    }
    
    if ($netbiosEnabledCount -gt 0) {
        Write-Host "[!] VULNERABLE: NetBIOS over TCP/IP is active on $($netbiosEnabledCount) interface(s)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] NetBIOS over TCP/IP is disabled on all interfaces." -ForegroundColor Green
    }
}

if ($vulnerable) {
    Write-Host "Audit result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableMulticastNameResolution.ps1
# Description: Disables LLMNR, NetBIOS over TCP/IP, and mDNS on all interfaces.

Write-Host "Applying hardening requirement: Disable Multicast Name Resolution..." -ForegroundColor Cyan

# 1. Disable LLMNR
$llmnrPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
if (-not (Test-Path $llmnrPath)) {
    New-Item -Path $llmnrPath -Force | Out-Null
}
Set-ItemProperty -Path $llmnrPath -Name "EnableMulticast" -Value 0 -Type DWord
Write-Host "LLMNR disabled via registry policy." -ForegroundColor Green

# 2. Disable mDNS
$mdnsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
if (-not (Test-Path $mdnsPath)) {
    New-Item -Path $mdnsPath -Force | Out-Null
}
Set-ItemProperty -Path $mdnsPath -Name "EnableMDNS" -Value 0 -Type DWord
Write-Host "mDNS disabled via registry." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all Network Adapters
$interfacesPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces"
if (Test-Path $interfacesPath) {
    $interfaces = Get-ChildItem -Path $interfacesPath
    foreach ($interface in $interfaces) {
        $intName = $interface.PSChildName
        $intPath = "$($interfacesPath)\$($intName)"
        Set-ItemProperty -Path $intPath -Name "NetbiosOptions" -Value 2 -Type DWord
        Write-Host "  NetBIOS disabled on interface: $($intName)" -ForegroundColor Gray
    }
    Write-Host "NetBIOS over TCP/IP disabled on all active interfaces." -ForegroundColor Green
} else {
    Write-Host "NetBIOS interfaces registry path not found." -ForegroundColor Yellow
}

Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-003] Disable NTLMv1</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-ntlmv1.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>NTLMv1 (NT LAN Manager version 1) is a legacy authentication protocol that relies on weak cryptographic primitives (specifically MD4 and DES). Because of these mathematical weaknesses, an attacker who intercepts NTLMv1 network authentication traffic can decrypt the responses offline in a matter of minutes, recovering the user's plaintext password or NT hash.</xhtml:p>
        <xhtml:p>By configuring the system to send only NTLMv2 responses and refuse both LM and NTLMv1 negotiations (corresponding to LAN Manager Compatibility Level 5), the system enforces the use of NTLMv2, which implements HMAC-MD5 and provides significantly stronger protection against offline cryptographic analysis. It also ensures that the directory environment moves closer to Kerberos-exclusive authentication.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: LAN Manager authentication level</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Send NTLMv2 response only. Refuse LM &amp; NTLM</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableNTLMv1.ps1">Download Script: Configure-DisableNTLMv1.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableNTLMv1.ps1
# Description: Restricts NTLM authentication to NTLMv2 and refuses NTLMv1 / LM.

Write-Host "Applying hardening requirement: Disable NTLMv1..." -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LmCompatibilityLevel" -Value 5 -Type DWord
Write-Host "LM Compatibility Level set to 5 (Send NTLMv2 response only. Refuse LM &amp; NTLM)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-NTLMv1Status.ps1">Download Script: Get-NTLMv1Status.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-NTLMv1Status.ps1
# Description: Audits the LM Compatibility Level setting in the registry.

Write-Host "--- Auditing NTLMv1 Restriction ---" -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$lsaReg = Get-ItemProperty -Path $regPath -Name "LmCompatibilityLevel" -ErrorAction SilentlyContinue

if ($lsaReg) {
    $lmVal = $lsaReg.LmCompatibilityLevel
    if ($lmVal -eq 5) {
        Write-Host "[+] NTLMv1 is disabled. LM Compatibility Level is set to $($lmVal) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: LM Compatibility Level is set to $($lmVal) (Required: 5)." -ForegroundColor Red
    }
} else {
    Write-Host "[!] VULNERABLE: LmCompatibilityLevel key is missing. System is using the default value (allows NTLMv1)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableNTLMv1.ps1
# Description: Restricts NTLM authentication to NTLMv2 and refuses NTLMv1 / LM.

Write-Host "Applying hardening requirement: Disable NTLMv1..." -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LmCompatibilityLevel" -Value 5 -Type DWord
Write-Host "LM Compatibility Level set to 5 (Send NTLMv2 response only. Refuse LM &amp; NTLM)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-004" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-004] Enforce LDAP Server Signing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enforce-ldap-signing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Lightweight Directory Access Protocol (LDAP) traffic transmitted over cleartext (TCP port 389) without signing is vulnerable to eavesdropping and man-in-the-middle (MitM) attacks. An adversary in a position to intercept network traffic can inject malicious payload packets, modify directory responses, or perform session hijacking.</xhtml:p>
        <xhtml:p>Enforcing LDAP signing ensures that the LDAP server (Domain Controller) rejects simple binds that are not encrypted or signed. It mandates data integrity verification via cryptographically secure signatures on the network packets. This directly mitigates the threat of LDAP relay and injection attacks, securing the communication path between directory clients and Domain Controllers.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to the Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Domain controller: LDAP server signing requirements</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Require signing</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the Domain Controllers OU.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-LDAPSigning.ps1">Download Script: Configure-LDAPSigning.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-LDAPSigning.ps1
# Description: Configures the LDAP server signing requirement to Require Signing.

Write-Host "Applying hardening requirement: Enforce LDAP Server Signing..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LDAPServerIntegrity" -Value 2 -Type DWord
Write-Host "LDAP Server Integrity set to 2 (Require Signing)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-LDAPSigningStatus.ps1">Download Script: Get-LDAPSigningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-LDAPSigningStatus.ps1
# Description: Audits the LDAP server signing configuration in the registry.

Write-Host "--- Auditing LDAP Server Signing ---" -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
$ntdsReg = Get-ItemProperty -Path $regPath -Name "LDAPServerIntegrity" -ErrorAction SilentlyContinue

if ($ntdsReg) {
    $integrityVal = $ntdsReg.LDAPServerIntegrity
    if ($integrityVal -eq 2) {
        Write-Host "[+] LDAP Server Signing is secure. LDAPServerIntegrity is set to $($integrityVal) (Require Signing)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: LDAPServerIntegrity is set to $($integrityVal) (Required: 2)." -ForegroundColor Red
    }
} else {
    Write-Host "[!] VULNERABLE: LDAPServerIntegrity registry value is missing. The system uses default negotiation (allows unsigned connections)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-LDAPSigning.ps1
# Description: Configures the LDAP server signing requirement to Require Signing.

Write-Host "Applying hardening requirement: Enforce LDAP Server Signing..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LDAPServerIntegrity" -Value 2 -Type DWord
Write-Host "LDAP Server Integrity set to 2 (Require Signing)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-005] Enforce LDAP Channel Binding</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enforce-ldap-channel-binding.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Adversaries use credential relay attacks (such as NTLM relaying) to intercept authentication challenges and replay them to other network services. In a coercion attack (e.g., the PetitPotam technique), an attacker forces a Domain Controller to authenticate to a malicious listener using NTLM. The attacker then relays these credentials to Active Directory Certificate Services (ADCS) or an LDAPS server to issue administrative certificates or modify directory databases.</xhtml:p>
        <xhtml:p>LDAP Channel Binding Tokens (CBT) mitigate these relay attacks. CBT establishes a cryptographic link between the transport-level security channel (TLS/SSL) and the application-level authentication protocol (SASL/NTLM/Kerberos). By requiring CBT verification on the LDAP server, the Domain Controller verifies that the authentication request originated from within the specific TLS channel used to send it. If an attacker attempts to relay credentials from a different session, the channel parameters will not match, and the Domain Controller will reject the authentication request.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to the Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Domain controller: LDAP server channel binding token requirements</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Always</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the Domain Controllers OU.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-LDAPChannelBinding.ps1">Download Script: Configure-LDAPChannelBinding.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-LDAPChannelBinding.ps1
# Description: Enforces LDAP Channel Binding Token requirements to Always.

Write-Host "Applying hardening requirement: Enforce LDAP Channel Binding..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
Write-Host "LDAP Channel Binding requirements set to 2 (Always)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-LDAPChannelBindingStatus.ps1">Download Script: Get-LDAPChannelBindingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-LDAPChannelBindingStatus.ps1
# Description: Audits the LDAP Channel Binding Token configuration in the registry.

Write-Host "--- Auditing LDAP Channel Binding ---" -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
$ntdsReg = Get-ItemProperty -Path $regPath -Name "LdapEnforceChannelBinding" -ErrorAction SilentlyContinue

if ($ntdsReg) {
    $cbtVal = $ntdsReg.LdapEnforceChannelBinding
    if ($cbtVal -eq 2) {
        Write-Host "[+] LDAP Channel Binding is secure. LdapEnforceChannelBinding is set to $($cbtVal) (Always)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: LdapEnforceChannelBinding is set to $($cbtVal) (Required: 2)." -ForegroundColor Red
    }
} else {
    Write-Host "[!] VULNERABLE: LdapEnforceChannelBinding registry value is missing. The system uses default settings (does not enforce CBT)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-LDAPChannelBinding.ps1
# Description: Enforces LDAP Channel Binding Token requirements to Always.

Write-Host "Applying hardening requirement: Enforce LDAP Channel Binding..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
Write-Host "LDAP Channel Binding requirements set to 2 (Always)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-006] Enable LSA Protection</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enable-lsa-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (LSASS) process (<xhtml:code>lsass.exe</xhtml:code>) is responsible for enforcing security policies, handling user authentication, and storing sensitive credential secrets (such as Kerberos tickets, NT hashes, and cached credentials) in memory. Adversaries who gain local administrative rights frequently target LSASS using memory-dumping tools (e.g., Mimikatz, Procdump) to extract these credentials, leading to domain-wide compromise and lateral movement.</xhtml:p>
        <xhtml:p>Enabling LSA Protection configures LSASS to run as a Protected Process Light (PPL). When running as a PPL, the operating system uses security boundaries to prevent non-protected processes (even those running with local administrator or SYSTEM privileges) from accessing LSASS memory space via debugging APIs (<xhtml:code>OpenProcess</xhtml:code> with read/write permissions) or injecting DLLs. This significantly increases the difficulty of offline credential harvesting.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Local Security Authority</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the following policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure LSA to run as a protected process</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Choose one of the following options</xhtml:em>*: <xhtml:code>Enabled with LSA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-LSAProtection.ps1">Download Script: Configure-LSAProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-LSAProtection.ps1
# Description: Enables LSA Protection (RunAsPPL) in the registry.

Write-Host "Applying hardening requirement: Enable LSA Protection..." -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "LSA Protection registry configuration applied. A reboot is required to activate." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-LSAProtectionStatus.ps1">Download Script: Get-LSAProtectionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-LSAProtectionStatus.ps1
# Description: Audits LSA Protection (RunAsPPL) in the registry.

Write-Host "--- Auditing LSA Protection ---" -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$lsaReg = Get-ItemProperty -Path $regPath -Name "RunAsPPL" -ErrorAction SilentlyContinue

if ($lsaReg) {
    $pplVal = $lsaReg.RunAsPPL
    if ($pplVal -eq 1) {
        Write-Host "[+] LSA Protection is enabled. RunAsPPL is set to $($pplVal) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: RunAsPPL is set to $($pplVal) (Required: 1)." -ForegroundColor Red
    }
} else {
    Write-Host "[!] VULNERABLE: RunAsPPL registry value is missing. LSA is not running as a protected process." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-LSAProtection.ps1
# Description: Enables LSA Protection (RunAsPPL) in the registry.

Write-Host "Applying hardening requirement: Enable LSA Protection..." -ForegroundColor Cyan

$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

Set-ItemProperty -Path $regPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "LSA Protection registry configuration applied. A reboot is required to activate." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-007" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-007] Disable Credential Guard</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-credential-guard.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Virtualization-Based Security (VBS) and Hypervisor-Protected Code Integrity (HVCI) should be enabled on Domain Controllers to protect the integrity of the operating system kernel and enforce driver blocklists.</xhtml:p>
        <xhtml:p>However, Windows Defender Credential Guard must <xhtml:strong>not</xhtml:strong> be deployed on Active Directory domain controllers. Credential Guard is designed to isolate LSA secrets to prevent credential-dumping tools from harvesting password hashes from local memory. Domain controllers do not store user credentials in LSASS memory in the same way member servers do; instead, credentials are stored securely in the Active Directory database (ntds.dit). Furthermore, domain controllers run LSASS in a manner that requires active cryptographic operations and delegation capabilities that are incompatible with the restrictions imposed by Credential Guard.</xhtml:p>
        <xhtml:p>Enabling Credential Guard on a domain controller can lead to authentication failures, block Kerberos delegation features, and cause operational instability without providing any security benefits.</xhtml:p>
        <xhtml:p>For official warnings and product specifications, refer to the Microsoft documentation: <xhtml:a href="https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/">Microsoft Security Guidance: Windows Defender Credential Guard Warnings</xhtml:a>
        </xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the following policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn On Virtualization-Based Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Virtualization Based Protection of Code Integrity</xhtml:em>*: <xhtml:code>Enabled with UEFI lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Credential Guard Configuration</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Require UEFI Memory Attributes Table</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Secure Launch Configuration</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Platform Security Level</xhtml:em>*: <xhtml:code>Secure Boot</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the settings locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableCredentialGuard.ps1">Download Script: Configure-DisableCredentialGuard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableCredentialGuard.ps1
# Description: Enables Virtualization-Based Security (VBS) and disables Credential Guard in the registry.

Write-Host "Applying hardening requirement: Enable VBS Baseline and Disable Credential Guard..." -ForegroundColor Cyan

# 1. Enable Virtualization-Based Security and related hypervisor options
$vbsPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $vbsPath)) {
    New-Item -Path $vbsPath -Force | Out-Null
}

$vbsSettings = @{
    "EnableVirtualizationBasedSecurity" = 1
    "HVCIMATRequired"                   = 1
    "ConfigureSystemGuardLaunch"        = 1
    "RequirePlatformSecurityFeatures"   = 1
    "HypervisorEnforcedCodeIntegrity"   = 1
}

foreach ($Setting in $vbsSettings.Keys) {
    Set-ItemProperty -Path $vbsPath -Name $Setting -Value $vbsSettings[$Setting] -Type DWord -ErrorAction Stop
}
Write-Host "Virtualization-Based Security parameters enabled in registry." -ForegroundColor Green

# 2. Disable Credential Guard (LsaCfgFlags: 0 = Disabled)
$lsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $lsaPath)) {
    New-Item -Path $lsaPath -Force | Out-Null
}
Set-ItemProperty -Path $lsaPath -Name "LsaCfgFlags" -Value 0 -Type DWord
Write-Host "Credential Guard configured to Disabled in registry." -ForegroundColor Green

Write-Host "Hardening applied successfully. A system reboot is required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit VBS and Credential Guard status using Registry and WMI:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-CredentialGuardStatus.ps1">Download Script: Get-CredentialGuardStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-CredentialGuardStatus.ps1
# Description: Audits the configuration and operational status of VBS and ensures Credential Guard is disabled.

Write-Host "--- Auditing VBS and Credential Guard Status ---" -ForegroundColor Cyan
$vulnerable = $false

# 1. Audit Registry Settings
$vbsRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
$lsaReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LsaCfgFlags" -ErrorAction SilentlyContinue

$ExpectedVbsSettings = @{
    "EnableVirtualizationBasedSecurity" = 1
    "HVCIMATRequired"                   = 1
    "ConfigureSystemGuardLaunch"        = 1
    "RequirePlatformSecurityFeatures"   = 1
    "HypervisorEnforcedCodeIntegrity"   = 1
}

if (Test-Path $vbsRegPath) {
    $vbsValues = Get-ItemProperty -Path $vbsRegPath -ErrorAction SilentlyContinue
    foreach ($Setting in $ExpectedVbsSettings.Keys) {
        $Val = $vbsValues.$Setting
        $Expected = $ExpectedVbsSettings[$Setting]
        if ($Val -eq $Expected) {
            Write-Host "[+] VBS setting '$Setting' is correctly configured ($Val)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: VBS setting '$Setting' is missing or incorrect ($Val)." -ForegroundColor Red
            $vulnerable = $true
        }
    }
} else {
    Write-Host "[!] VULNERABLE: Virtualization-Based Security registry path does not exist." -ForegroundColor Red
    $vulnerable = $true
}

# For DCs, Credential Guard (LsaCfgFlags) must be set to 0 (Disabled)
if ($null -ne $lsaReg -and $lsaReg.LsaCfgFlags -ne 0) {
    Write-Host "[!] VULNERABLE: Credential Guard is enabled in registry (LsaCfgFlags = $($lsaReg.LsaCfgFlags))." -ForegroundColor Red
    $vulnerable = $true
} else {
    $val = if ($null -eq $lsaReg) { "Not configured (Disabled)" } else { $lsaReg.LsaCfgFlags }
    Write-Host "[+] Credential Guard registry key 'LsaCfgFlags' is correctly set to disabled ($val)." -ForegroundColor Green
}

# 2. Audit WMI Operational State (if running)
$deviceGuard = Get-CimInstance -Namespace "root\cimv2" -ClassName "Win32_DeviceGuard" -ErrorAction SilentlyContinue
if ($deviceGuard) {
    # SecurityServicesRunning: 1 = Credential Guard
    $servicesRunning = $deviceGuard.SecurityServicesRunning
    $cgRunning = $false
    foreach ($service in $servicesRunning) {
        if ($service -eq 1) { $cgRunning = $true }
    }
    
    if ($cgRunning) {
        Write-Host "[!] VULNERABLE: Credential Guard is running operationally on this Domain Controller." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] Credential Guard is not running on this Domain Controller." -ForegroundColor Green
    }
} else {
    Write-Host "[-] WMI class Win32_DeviceGuard is not available." -ForegroundColor Yellow
}

if ($vulnerable) {
    Write-Host "Audit result: VULNERABLE (Credential Guard enabled or VBS misconfigured)" -ForegroundColor Red
} else {
    Write-Host "Audit result: SECURE (Credential Guard disabled and VBS configured)" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableCredentialGuard.ps1
# Description: Enables Virtualization-Based Security (VBS) and disables Credential Guard in the registry.

Write-Host "Applying hardening requirement: Enable VBS Baseline and Disable Credential Guard..." -ForegroundColor Cyan

# 1. Enable Virtualization-Based Security and related hypervisor options
$vbsPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $vbsPath)) {
    New-Item -Path $vbsPath -Force | Out-Null
}

$vbsSettings = @{
    "EnableVirtualizationBasedSecurity" = 1
    "HVCIMATRequired"                   = 1
    "ConfigureSystemGuardLaunch"        = 1
    "RequirePlatformSecurityFeatures"   = 1
    "HypervisorEnforcedCodeIntegrity"   = 1
}

foreach ($Setting in $vbsSettings.Keys) {
    Set-ItemProperty -Path $vbsPath -Name $Setting -Value $vbsSettings[$Setting] -Type DWord -ErrorAction Stop
}
Write-Host "Virtualization-Based Security parameters enabled in registry." -ForegroundColor Green

# 2. Disable Credential Guard (LsaCfgFlags: 0 = Disabled)
$lsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $lsaPath)) {
    New-Item -Path $lsaPath -Force | Out-Null
}
Set-ItemProperty -Path $lsaPath -Name "LsaCfgFlags" -Value 0 -Type DWord
Write-Host "Credential Guard configured to Disabled in registry." -ForegroundColor Green

Write-Host "Hardening applied successfully. A system reboot is required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2007" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-008" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-008] Disable Print Spooler Service</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-print-spooler.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Print Spooler service (<xhtml:code>Spooler</xhtml:code>) is enabled and running by default on Windows Server installations, including Domain Controllers. However, Domain Controllers do not print and should never act as print servers.</xhtml:p>
        <xhtml:p>The Print Spooler service has a history of high-severity vulnerabilities, including remote code execution exploits (e.g., the PrintNightmare vulnerability family - CVE-2021-1675 / CVE-2021-34527). Additionally, the service is exploited in coercion attacks such as the PetitPotam technique or printer-based authentication coercion. An attacker with low-privilege network access can send an RPC request to the DC's Print Spooler service (specifically utilizing APIs such as <xhtml:code>RpcRemoteFindFirstPrinterChangeNotificationEx</xhtml:code>), forcing the Domain Controller to authenticate to a malicious listener over NTLM. The attacker can then relay this authentication to take over the Active Directory domain. Disabling the service completely closes these high-risk vectors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to the Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Find the <xhtml:strong>Print Spooler</xhtml:strong> service in the list and double-click it.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the Domain Controllers OU.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisablePrintSpooler.ps1">Download Script: Configure-DisablePrintSpooler.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisablePrintSpooler.ps1
# Description: Stops and disables the Print Spooler service.

Write-Host "Applying hardening requirement: Disable Print Spooler..." -ForegroundColor Cyan

$serviceName = "Spooler"
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue

if ($service) {
    if ($service.Status -eq "Running") {
        Write-Host "Stopping service $($serviceName)..." -ForegroundColor Gray
        Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
    }
    
    # Configure startup type to disabled
    Set-Service -Name $serviceName -StartupType Disabled
    Write-Host "Service $($serviceName) has been stopped and disabled." -ForegroundColor Green
} else {
    Write-Host "Service $($serviceName) not found." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-PrintSpoolerStatus.ps1">Download Script: Get-PrintSpoolerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PrintSpoolerStatus.ps1
# Description: Audits the operational status and startup type of the Print Spooler service.

Write-Host "--- Auditing Print Spooler Service ---" -ForegroundColor Cyan

$serviceName = "Spooler"
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue

if ($service) {
    $status = $service.Status
    $startType = $service.StartType
    
    if ($status -eq "Stopped" -and $startType -eq "Disabled") {
        Write-Host "[+] Print Spooler is secure (Stopped and Disabled)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Print Spooler service status is $($status) and StartType is $($startType) (Required: Stopped &amp; Disabled)." -ForegroundColor Red
    }
} else {
    Write-Host "[+] Print Spooler service is not installed on this system (Secure)." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePrintSpooler.ps1
# Description: Stops and disables the Print Spooler service.

Write-Host "Applying hardening requirement: Disable Print Spooler..." -ForegroundColor Cyan

$serviceName = "Spooler"
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue

if ($service) {
    if ($service.Status -eq "Running") {
        Write-Host "Stopping service $($serviceName)..." -ForegroundColor Gray
        Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
    }
    
    # Configure startup type to disabled
    Set-Service -Name $serviceName -StartupType Disabled
    Write-Host "Service $($serviceName) has been stopped and disabled." -ForegroundColor Green
} else {
    Write-Host "Service $($serviceName) not found." -ForegroundColor Yellow
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2008" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-009" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-009] Enforce SMB Message Signing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enforce-smb-signing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Server Message Block (SMB) authentication is vulnerable to man-in-the-middle (MitM) and relay attacks. If SMB signing is not enforced, an attacker positioned on the local network can intercept SMB authentication sessions from client systems and relay them to another host (e.g., a Domain Controller or high-value member server). If the relayed user credential possesses administrative rights on the target host, the attacker can execute commands remotely (e.g., via PsExec/WMI) and compromise the system without knowing the password.</xhtml:p>
        <xhtml:p>Enforcing SMB signing ensures that all SMB packets are digitally signed using session keys. This guarantees the authenticity of both the sender and the receiver and ensures packet integrity. If an attacker attempts to relay or modify the packets, the cryptographic signature check fails, and the session is terminated. Enforcing this on both server and client roles is a fundamental defense against lateral movement and domain takeover.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Microsoft network server: Digitally sign communications (always)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Microsoft network client: Digitally sign communications (always)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the settings locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-SMBSigning.ps1">Download Script: Configure-SMBSigning.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-SMBSigning.ps1
# Description: Enforces SMB signing for both SMB server and client.

Write-Host "Applying hardening requirement: Enforce SMB Message Signing..." -ForegroundColor Cyan

# 1. Enforce Server SMB Signing
$srvRegPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $srvRegPath)) {
    New-Item -Path $srvRegPath -Force | Out-Null
}
Set-ItemProperty -Path $srvRegPath -Name "RequireSecuritySignature" -Value 1 -Type DWord
Write-Host "SMB Server signing (always) enabled." -ForegroundColor Green

# 2. Enforce Client SMB Signing
$cliRegPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
if (-not (Test-Path $cliRegPath)) {
    New-Item -Path $cliRegPath -Force | Out-Null
}
Set-ItemProperty -Path $cliRegPath -Name "RequireSecuritySignature" -Value 1 -Type DWord
Write-Host "SMB Client signing (always) enabled." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-SMBSigningStatus.ps1">Download Script: Get-SMBSigningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SMBSigningStatus.ps1
# Description: Audits the registry settings for SMB server and client signing.

Write-Host "--- Auditing SMB Message Signing ---" -ForegroundColor Cyan
$vulnerable = $false

# 1. Audit Server-side SMB Signing
$srvReg = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters" -Name "RequireSecuritySignature" -ErrorAction SilentlyContinue
if ($srvReg -and $srvReg.RequireSecuritySignature -eq 1) {
    Write-Host "[+] SMB Server signing is enforced (RequireSecuritySignature = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: SMB Server signing is NOT enforced." -ForegroundColor Red
    $vulnerable = $true
}

# 2. Audit Client-side SMB Signing
$cliReg = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" -Name "RequireSecuritySignature" -ErrorAction SilentlyContinue
if ($cliReg -and $cliReg.RequireSecuritySignature -eq 1) {
    Write-Host "[+] SMB Client signing is enforced (RequireSecuritySignature = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: SMB Client signing is NOT enforced." -ForegroundColor Red
    $vulnerable = $true
}

if ($vulnerable) {
    Write-Host "Audit result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-SMBSigning.ps1
# Description: Enforces SMB signing for both SMB server and client.

Write-Host "Applying hardening requirement: Enforce SMB Message Signing..." -ForegroundColor Cyan

# 1. Enforce Server SMB Signing
$srvRegPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $srvRegPath)) {
    New-Item -Path $srvRegPath -Force | Out-Null
}
Set-ItemProperty -Path $srvRegPath -Name "RequireSecuritySignature" -Value 1 -Type DWord
Write-Host "SMB Server signing (always) enabled." -ForegroundColor Green

# 2. Enforce Client SMB Signing
$cliRegPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
if (-not (Test-Path $cliRegPath)) {
    New-Item -Path $cliRegPath -Force | Out-Null
}
Set-ItemProperty -Path $cliRegPath -Name "RequireSecuritySignature" -Value 1 -Type DWord
Write-Host "SMB Client signing (always) enabled." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2009" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-010" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-010] Restrict Kerberos Encryption Types</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/restrict-kerberos-encryption.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory uses the Kerberos version 5 protocol as its primary authentication mechanism. By default, Active Directory maintains backward compatibility with legacy cryptographic suites, including Data Encryption Standard (DES) and Rivest Cipher 4 (RC4-HMAC). Allowing these legacy ciphers introduces severe architectural vulnerabilities:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Cryptographic Weaknesses of RC4-HMAC (RFC 4757)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Derivation Flaw</xhtml:em>*: Under the RC4-HMAC Kerberos specification, the long-term secret key used to encrypt tickets is identical to the user's NTLM password hash (<xhtml:code>MD4(UTF-16LE(password))</xhtml:code>). No salt, no iteration count, and no cryptographic key derivation function (KDF) stretching are applied.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>AES vs. RC4 Cryptography</xhtml:em>*: In contrast, Kerberos AES encryption (RFC 3961 and RFC 3962) utilizes PBKDF2 with HMAC-SHA1, an account-specific salt (<xhtml:code>DOMAINusername</xhtml:code>), and a default work factor of 4,096 iterations. Cracking an AES Kerberos key requires exponentially more computational effort per guess than RC4.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Kerberoasting &amp; Cipher Downgrade Attacks (MITRE ATT&amp;CK T1558.003)</xhtml:strong>:</xhtml:li>
          <xhtml:li>* Any authenticated domain user can request a Ticket Granting Service (TGS) ticket for any account with a registered Service Principal Name (SPN).</xhtml:li>
          <xhtml:li>* In a cipher downgrade attack, an attacker crafts a Kerberos <xhtml:code>TGS-REQ</xhtml:code> specifying only <xhtml:code>rc4-hmac</xhtml:code> (encryption type <xhtml:code>23</xhtml:code>) in the requested encryption type list. If RC4 is permitted on the Key Distribution Center (KDC), the KDC issues an RC4-encrypted service ticket—even if the target service account supports AES.</xhtml:li>
          <xhtml:li>* Because RC4 tickets use the raw NTLM hash, attackers can crack the extracted ticket offline using modern GPU rigs (Hashcat mode <xhtml:code>13100</xhtml:code>) at rates exceeding billions of guesses per second. By restricting KDC encryption types to AES-128 and AES-256, the KDC strictly rejects requests for weak ciphers, neutralizing Kerberoasting downgrade attacks.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>AS-REP Roasting Protection (MITRE ATT&amp;CK T1558.004)</xhtml:strong>:</xhtml:li>
          <xhtml:li>* For accounts with Kerberos pre-authentication disabled (<xhtml:code>DONT_REQ_PREAUTH</xhtml:code> flag enabled), any domain user can request an AS-REP authentication ticket from the KDC without supplying credentials.</xhtml:li>
          <xhtml:li>* If RC4 is enabled, the returned AS-REP ticket is encrypted using the target account's RC4/NTLM hash, allowing high-speed offline dictionary attacks (Hashcat mode <xhtml:code>18200</xhtml:code>). Enforcing AES ensures the KDC encrypts the AS-REP using PBKDF2-stretched AES keys.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Mitigating Forged Golden &amp; Silver Tickets (MITRE ATT&amp;CK T1558.001 / T1558.002)</xhtml:strong>:</xhtml:li>
          <xhtml:li>* When an attacker extracts NTLM password hashes (e.g., via DCSync against <xhtml:code>krbtgt</xhtml:code> or a service account), they can forge arbitrary Kerberos Ticket Granting Tickets (TGTs - Golden Tickets) or Service Tickets (Silver Tickets) using RC4.</xhtml:li>
          <xhtml:li>* When RC4 is disabled domain-wide, domain members and Domain Controllers reject RC4-encrypted tickets outright. Attackers are forced to obtain the actual AES-128 or AES-256 keys, which are not exposed through simple NTLM hash dumping or relay mechanisms.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>PAC Signature Integrity &amp; CVE-2022-37967 Enforcement</xhtml:strong>:</xhtml:li>
          <xhtml:li>* The Privilege Attribute Certificate (PAC) contains the user's authorization data, security identifiers (SIDs), and group memberships.</xhtml:li>
          <xhtml:li>* Security updates for CVE-2022-37967 / KB5020805 require strong HMAC-SHA1 AES algorithms for PAC signatures (<xhtml:code>KERB_CHECKSUM_HMAC_SHA1_96_AES128</xhtml:code> / <xhtml:code>KERB_CHECKSUM_HMAC_SHA1_96_AES256</xhtml:code>). Disabling RC4 guarantees consistent cryptographic security across ticket encryption, session key derivation, and PAC checksum verification.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Overpass-the-Hash / Pass-the-Key Defense</xhtml:strong>:</xhtml:li>
          <xhtml:li>* In an Overpass-the-Hash attack, an attacker uses an NTLM hash as the Kerberos RC4 key to request a valid TGT. Enforcing AES-only requires authentication to use AES keys, preventing attackers from converting raw NTLM hashes into Kerberos tickets.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Configure encryption types allowed for Kerberos</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: Check only the following boxes:</xhtml:li>
          <xhtml:li>* <xhtml:code>AES128_HMAC_SHA1</xhtml:code>
          </xhtml:li>
          <xhtml:li>* <xhtml:code>AES256_HMAC_SHA1</xhtml:code>
          </xhtml:li>
          <xhtml:li>* <xhtml:code>Future encryption types</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-KerberosEncryptionTypes.ps1">Download Script: Configure-KerberosEncryptionTypes.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-KerberosEncryptionTypes.ps1
# Description: Restricts Kerberos encryption types to AES128, AES256, and Future types.

Write-Host "Applying hardening requirement: Restrict Kerberos Encryption Types..." -ForegroundColor Cyan

$regPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

# 2147483640 (0x7FFFFFF8) enables AES128, AES256, and Future encryption types
Set-ItemProperty -Path $regPath -Name "SupportedEncryptionTypes" -Value 2147483640 -Type DWord
Write-Host "Kerberos encryption types restricted to AES and future types." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-KerberosEncryptionStatus.ps1">Download Script: Get-KerberosEncryptionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KerberosEncryptionStatus.ps1
# Description: Audits the allowed Kerberos encryption types in the registry.

Write-Host "--- Auditing Kerberos Encryption Types ---" -ForegroundColor Cyan

$regPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$regVal = Get-ItemProperty -Path $regPath -Name "SupportedEncryptionTypes" -ErrorAction SilentlyContinue

if ($regVal) {
    $encTypes = $regVal.SupportedEncryptionTypes
    
    # Check if weak algorithms are enabled (DES = 0x1, 0x2; RC4 = 0x4)
    $hasDES = ($encTypes -band 0x1) -or ($encTypes -band 0x2)
    $hasRC4 = ($encTypes -band 0x4)
    $hasAES128 = ($encTypes -band 0x8)
    $hasAES256 = ($encTypes -band 0x10)
    
    if ($hasDES -or $hasRC4) {
        Write-Host "[!] VULNERABLE: Weak Kerberos encryption algorithms are allowed (DES: $($hasDES), RC4: $($hasRC4)). SupportedEncryptionTypes raw value: $($encTypes)." -ForegroundColor Red
    } else {
        if ($hasAES128 -and $hasAES256) {
            Write-Host "[+] Kerberos encryption is secure. Restricting to AES128/AES256 (SupportedEncryptionTypes: $($encTypes))." -ForegroundColor Green
        } else {
            Write-Host "[-] Kerberos encryption configuration is custom. AES128: $($hasAES128), AES256: $($hasAES256) (SupportedEncryptionTypes: $($encTypes))." -ForegroundColor Yellow
        }
    }
} else {
    Write-Host "[!] VULNERABLE: SupportedEncryptionTypes registry value is missing. Default behavior allows insecure RC4." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-KerberosEncryptionTypes.ps1
# Description: Restricts Kerberos encryption types to AES128, AES256, and Future types.

Write-Host "Applying hardening requirement: Restrict Kerberos Encryption Types..." -ForegroundColor Cyan

$regPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

# 2147483640 (0x7FFFFFF8) enables AES128, AES256, and Future encryption types
Set-ItemProperty -Path $regPath -Name "SupportedEncryptionTypes" -Value 2147483640 -Type DWord
Write-Host "Kerberos encryption types restricted to AES and future types." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-011" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-011] Restrict Remote SAM API Access</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10 (1607+), Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/restrict-ntds-sam-api.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>By default, the Security Account Manager (SAM) and NT Directory Services (NTDS) allow remote RPC connections from non-privileged accounts. Using these connections, an attacker who has established a foothold in the network (even with a basic, non-administrative domain user account) can query the Domain Controller or member servers to enumerate local users, group memberships, and security policies.</xhtml:p>
        <xhtml:p>Tools like BloodHound/SharpHound, or simple commands like <xhtml:code>net user /domain</xhtml:code>, rely on these remote SAM RPC interfaces to extract information for network profiling and lateral movement mapping. Restricting remote client access to the SAM API (utilizing <xhtml:code>RestrictRemoteSAM</xhtml:code>) ensures that only members of the built-in Administrators group can make remote RPC queries. This significantly reduces the recon capabilities of an internal attacker.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network access: Restrict clients allowed to make remote calls to SAM</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>
            <xhtml:em>: Click </xhtml:em>
            <xhtml:em>Edit Security</xhtml:em>* and configure the permissions. By default, only local Administrators are granted access. Ensure the SDDL translates to <xhtml:code>O:BAG:BAD:(A;;RC;;;BA)</xhtml:code>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-RestrictRemoteSAM.ps1">Download Script: Configure-RestrictRemoteSAM.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-RestrictRemoteSAM.ps1
# Description: Restricts remote RPC access to the SAM database to local Administrators.

Write-Host "Applying hardening requirement: Restrict Remote SAM API Access..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

$sddl = "O:BAG:BAD:(A;;RC;;;BA)"
Set-ItemProperty -Path $regPath -Name "RestrictRemoteSAM" -Value $sddl -Type String
Write-Host "SAM remote API access restricted to Administrators (SDDL applied)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-RestrictRemoteSAMStatus.ps1">Download Script: Get-RestrictRemoteSAMStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-RestrictRemoteSAMStatus.ps1
# Description: Audits the RestrictRemoteSAM registry value.

Write-Host "--- Auditing RestrictRemoteSAM ---" -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$lsaReg = Get-ItemProperty -Path $regPath -Name "RestrictRemoteSAM" -ErrorAction SilentlyContinue

if ($lsaReg) {
    $sddlVal = $lsaReg.RestrictRemoteSAM
    if ($sddlVal -eq "O:BAG:BAD:(A;;RC;;;BA)") {
        Write-Host "[+] Remote SAM access is secure. RestrictRemoteSAM matches expected SDDL: $($sddlVal)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: RestrictRemoteSAM is configured but has a different SDDL: $($sddlVal) (Expected: O:BAG:BAD:(A;;RC;;;BA))." -ForegroundColor Red
    }
} else {
    Write-Host "[!] VULNERABLE: RestrictRemoteSAM registry key is missing. System allows remote SAM enumeration by standard users." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-RestrictRemoteSAM.ps1
# Description: Restricts remote RPC access to the SAM database to local Administrators.

Write-Host "Applying hardening requirement: Restrict Remote SAM API Access..." -ForegroundColor Cyan

$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $regPath)) {
    New-Item -Path $regPath -Force | Out-Null
}

$sddl = "O:BAG:BAD:(A;;RC;;;BA)"
Set-ItemProperty -Path $regPath -Name "RestrictRemoteSAM" -Value $sddl -Type String
Write-Host "SAM remote API access restricted to Administrators (SDDL applied)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-013" severity="medium" weight="10.0" selected="false">
      <title>[REQ-DC-013] Enable Kerberos Armoring</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enable-kerberos-armoring.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory environments relying on standard Kerberos authentication are susceptible to offline brute-force, dictionary attacks, and credential harvesting. During the initial Kerberos pre-authentication phase, the client requests a Ticket Granting Ticket (TGT) in clear text by sending an AS-REQ containing encrypted timestamps. Attackers monitoring network traffic can intercept these exchanges, or perform AS-REP roasting against accounts that do not require pre-authentication, conducting offline password cracking to compromise credentials.</xhtml:p>
        <xhtml:p>Kerberos Armoring, also known as Flexible Authentication Secure Tunneling (FAST - RFC 6113), mitigates this vulnerability by establishing an encrypted channel (a secure tunnel) between the Kerberos client and the Key Distribution Center (KDC) on the Domain Controller. This tunnel is encrypted using the computer account's credential (or the local system's credential), protecting the pre-authentication messages (AS-REQ and AS-REP) from eavesdropping, offline dictionary attacks, and tampering.</xhtml:p>
        <xhtml:p>Additionally, Kerberos Armoring is a strict prerequisite for Dynamic Access Control (DAC), Compound Authentication (which validates both the user's and the device's identities before granting access), and Authentication Silos. On Windows Server 2016 and newer domain controllers, configuring KDC support for the PKInit Freshness Extension (RFC 8070) further strengthens public key authentication by ensuring that certificates cannot be reused in pre-authentication replay attacks.</xhtml:p>
        <xhtml:p>Domain Controllers function both as KDC servers handling authentication requests and as Kerberos clients during domain controller replication, directory operations, and inter-forest authentication. Consequently, both KDC-side and client-side Kerberos armoring policies must be enabled on all Domain Controllers.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Configure Domain Controller KDC Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management workstation.</xhtml:li>
          <xhtml:li>Edit the Domain Controllers hardening GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\KDC</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>KDC support for claims, compound authentication and Kerberos armoring</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>*: Select <xhtml:code>Supported</xhtml:code> from the dropdown list (upgrade to <xhtml:code>Fail unarmored authentication requests</xhtml:code> only after full client rollout and validation).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>KDC support for PKInit Freshness Extension</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>*: Select <xhtml:code>Supported</xhtml:code> from the dropdown list.</xhtml:li>
          <xhtml:li>Link the GPO to the Domain Controllers Organizational Unit.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Configure Domain Controller Client Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same Domain Controllers hardening GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Kerberos</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Kerberos client support for claims, compound authentication and Kerberos armoring` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Support device authentication using certificate` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>Automatic</xhtml:code> in options)</xhtml:li>
          <xhtml:li>Ensure the GPO is enforced across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for testing or standalone systems) or if the control is not manageable via standard GPO GUI interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-KerberosArmoring.ps1">Download Script: Configure-KerberosArmoring.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-KerberosArmoring.ps1
# Description: Configures Kerberos Armoring (FAST) and PKInit Freshness Extension registry settings on Domain Controllers and Kerberos clients.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring (FAST) on Domain Controllers..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$KdcRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"

# Configure client-side settings (applicable to all systems, including DCs for DC-to-DC authentication)
if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord
Write-Host "Client-side Kerberos Armoring and Device Certificate Authentication enabled successfully." -ForegroundColor Green

# Determine if the host is a Domain Controller
$DomainRole = (Get-CimInstance -ClassName Win32_ComputerSystem).DomainRole
$IsDC = ($DomainRole -eq 4) -or ($DomainRole -eq 5)

if ($IsDC) {
    Write-Host "Domain Controller detected. Enabling KDC support for Kerberos Armoring and PKInit Freshness..." -ForegroundColor Cyan
    if (-not (Test-Path $KdcRegPath)) {
        New-Item -Path $KdcRegPath -Force | Out-Null
    }
    
    # Value 1 = Supported (Safe deployment baseline)
    # Value 3 = Fail unarmored authentication requests (Strict/Enforced state)
    Set-ItemProperty -Path $KdcRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord
    Set-ItemProperty -Path $KdcRegPath -Name "CbacAndArmorLevel" -Value 1 -Type DWord
    # Value 1 = Supported for PKInit Freshness Extension (RFC 8070)
    Set-ItemProperty -Path $KdcRegPath -Name "PKINITFreshness" -Value 1 -Type DWord
    Write-Host "KDC support for claims, armoring (Supported: 1), and PKInit Freshness enabled successfully." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-KerberosArmoringStatus.ps1">Download Script: Get-KerberosArmoringStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KerberosArmoringStatus.ps1
# Description: Audits the Kerberos Armoring (FAST) and PKInit Freshness configuration on Domain Controllers and clients.

Write-Host "--- Auditing Kerberos Armoring (FAST) Configuration ---" -ForegroundColor Cyan

$DomainRole = (Get-CimInstance -ClassName Win32_ComputerSystem).DomainRole
$IsDC = ($DomainRole -eq 4) -or ($DomainRole -eq 5)
$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$KdcRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"

$Vulnerable = $false

# 1. Audit Client-side support
$ClientValue = Get-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue
$DevicePKInit = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -ErrorAction SilentlyContinue
$DeviceBehavior = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -ErrorAction SilentlyContinue

if ($null -ne $ClientValue -and $ClientValue.EnableCbacAndArmor -eq 1) {
    Write-Host "[+] Client-side Kerberos Armoring is ENABLED (EnableCbacAndArmor = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Client-side Kerberos Armoring is DISABLED or missing." -ForegroundColor Red
    $Vulnerable = $true
}

if ($null -ne $DevicePKInit -and $DevicePKInit.DevicePKInitEnabled -eq 1 -and $null -ne $DeviceBehavior -and $DeviceBehavior.DevicePKInitBehavior -eq 0) {
    Write-Host "[+] Certificate device authentication is ENABLED: Automatic." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Certificate device authentication is not compliant or not configured." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Audit KDC support if Domain Controller
if ($IsDC) {
    Write-Host "Domain Controller detected. Auditing KDC support..." -ForegroundColor Cyan
    $KdcCbac = Get-ItemProperty -Path $KdcRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue
    $KdcLevel = Get-ItemProperty -Path $KdcRegPath -Name "CbacAndArmorLevel" -ErrorAction SilentlyContinue
    $KdcFresh = Get-ItemProperty -Path $KdcRegPath -Name "PKINITFreshness" -ErrorAction SilentlyContinue

    if ($null -ne $KdcCbac -and $KdcCbac.EnableCbacAndArmor -eq 1 -and $null -ne $KdcLevel) {
        $LevelVal = $KdcLevel.CbacAndArmorLevel
        if ($LevelVal -eq 1) {
            Write-Host "[+] KDC support for claims and armoring is ENABLED (Supported: 1)." -ForegroundColor Green
        } elseif ($LevelVal -eq 2) {
            Write-Host "[+] KDC support for claims and armoring is ENABLED (Always provide claims: 2)." -ForegroundColor Green
        } elseif ($LevelVal -eq 3) {
            Write-Host "[+] KDC support for claims and armoring is ENABLED and ENFORCED (Fail unarmored: 3)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: KDC CbacAndArmorLevel configured with invalid value: $($LevelVal)." -ForegroundColor Red
            $Vulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: KDC support for claims and armoring is MISSING or misconfigured." -ForegroundColor Red
        $Vulnerable = $true
    }

    if ($null -ne $KdcFresh -and ($KdcFresh.PKINITFreshness -eq 1 -or $KdcFresh.PKINITFreshness -eq 2)) {
        Write-Host "[+] KDC PKInit Freshness Extension is ENABLED (Value: $($KdcFresh.PKINITFreshness))." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: KDC PKInit Freshness Extension is MISSING or disabled." -ForegroundColor Red
        $Vulnerable = $true
    }
}

if ($Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-KerberosArmoring.ps1
# Description: Configures Kerberos Armoring (FAST) and PKInit Freshness Extension registry settings on Domain Controllers and Kerberos clients.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring (FAST) on Domain Controllers..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$KdcRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"

# Configure client-side settings (applicable to all systems, including DCs for DC-to-DC authentication)
if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord
Write-Host "Client-side Kerberos Armoring and Device Certificate Authentication enabled successfully." -ForegroundColor Green

# Determine if the host is a Domain Controller
$DomainRole = (Get-CimInstance -ClassName Win32_ComputerSystem).DomainRole
$IsDC = ($DomainRole -eq 4) -or ($DomainRole -eq 5)

if ($IsDC) {
    Write-Host "Domain Controller detected. Enabling KDC support for Kerberos Armoring and PKInit Freshness..." -ForegroundColor Cyan
    if (-not (Test-Path $KdcRegPath)) {
        New-Item -Path $KdcRegPath -Force | Out-Null
    }
    
    # Value 1 = Supported (Safe deployment baseline)
    # Value 3 = Fail unarmored authentication requests (Strict/Enforced state)
    Set-ItemProperty -Path $KdcRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord
    Set-ItemProperty -Path $KdcRegPath -Name "CbacAndArmorLevel" -Value 1 -Type DWord
    # Value 1 = Supported for PKInit Freshness Extension (RFC 8070)
    Set-ItemProperty -Path $KdcRegPath -Name "PKINITFreshness" -Value 1 -Type DWord
    Write-Host "KDC support for claims, armoring (Supported: 1), and PKInit Freshness enabled successfully." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2013" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-014" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-014] Restrict NTLM</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/restrict-ntlm.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The NT LAN Manager (NTLM) authentication protocol is legacy, cryptographically weak, and lacks support for modern security primitives such as mutual authentication. Adversaries exploit NTLM through credential relaying attacks (e.g., replaying captured authentication responses to other network services) and coercion techniques (e.g., PetitPotam or printer spooler RPC abuse).</xhtml:p>
        <xhtml:p>By auditing and subsequently restricting NTLM authentication incoming to, outgoing from, and within the Active Directory domain, organizations significantly mitigate the risks of credential relaying, offline password cracking, and unauthorized lateral movement. Restricting NTLM pushes client machines and application servers to utilize Kerberos, which provides robust mutual authentication and support for advanced cryptographic algorithms. Microsoft has also announced the eventual deprecation of NTLM, making active restriction an essential step in future-proofing active directory directory services.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Phase 1: Enable Auditing (Apply to Domain Controllers, Servers, and Clients)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following audit policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Audit NTLM authentication in this domain</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enable all</xhtml:code> (Apply to Domain Controllers)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Audit Incoming NTLM Traffic</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enable auditing for all accounts</xhtml:code> (Apply to DCs, member servers, and clients)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Audit all</xhtml:code> (Apply to DCs, member servers, and clients)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Phase 2: Enforce Restrictions (Apply after logs have been verified and exception lists populated)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following restriction policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: NTLM authentication in this domain</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Deny for domain accounts</xhtml:code> (Apply to Domain Controllers)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Incoming NTLM Traffic</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Deny all accounts</xhtml:code> (Apply to member servers and clients)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Deny all</xhtml:code> (Apply to member servers and clients)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: Configure the server hostnames or FQDNs that require exemption.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for testing or standalone systems) or if the control is not manageable via standard GPO GUI interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-RestrictNTLM.ps1">Download Script: Configure-RestrictNTLM.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-RestrictNTLM.ps1
# Description: Configures local registry values to enforce NTLM restrictions and auditing.

Write-Host "Applying hardening requirement: Restrict NTLM..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
$NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"

# Ensure LSA MSV1_0 path exists and apply settings
if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "AuditReceivingNTLMTraffic" -Value 2 -Type DWord
Set-ItemProperty -Path $LsaPath -Name "RestrictReceivingNTLMTraffic" -Value 2 -Type DWord
Set-ItemProperty -Path $LsaPath -Name "RestrictSendingNTLMTraffic" -Value 2 -Type DWord

# Ensure Netlogon Parameters path exists and apply settings
if (-not (Test-Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}

Set-ItemProperty -Path $NetlogonPath -Name "AuditNTLMInDomain" -Value 7 -Type DWord
Set-ItemProperty -Path $NetlogonPath -Name "RestrictNTLMInDomain" -Value 3 -Type DWord

Write-Host "NTLM restriction registry configurations applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-RestrictNTLMStatus.ps1">Download Script: Get-RestrictNTLMStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-RestrictNTLMStatus.ps1
# Description: Audits the registry configuration for NTLM auditing and restrictions.

Write-Host "--- Auditing NTLM Restrictions ---" -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
$NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"

if (Test-Path $LsaPath) {
    $AuditRecv = Get-ItemProperty -Path $LsaPath -Name "AuditReceivingNTLMTraffic" -ErrorAction SilentlyContinue
    if ($AuditRecv) {
        Write-Host "[+] AuditReceivingNTLMTraffic is set to $($AuditRecv.AuditReceivingNTLMTraffic) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: AuditReceivingNTLMTraffic is not configured." -ForegroundColor Red
    }

    $RestrictRecv = Get-ItemProperty -Path $LsaPath -Name "RestrictReceivingNTLMTraffic" -ErrorAction SilentlyContinue
    if ($RestrictRecv) {
        Write-Host "[+] RestrictReceivingNTLMTraffic is set to $($RestrictRecv.RestrictReceivingNTLMTraffic) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: RestrictReceivingNTLMTraffic is not configured." -ForegroundColor Red
    }

    $RestrictSend = Get-ItemProperty -Path $LsaPath -Name "RestrictSendingNTLMTraffic" -ErrorAction SilentlyContinue
    if ($RestrictSend) {
        Write-Host "[+] RestrictSendingNTLMTraffic is set to $($RestrictSend.RestrictSendingNTLMTraffic) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: RestrictSendingNTLMTraffic is not configured." -ForegroundColor Red
    }
} else {
    Write-Host "[!] LSA MSV1_0 path does not exist." -ForegroundColor Red
}

if (Test-Path $NetlogonPath) {
    $AuditDomain = Get-ItemProperty -Path $NetlogonPath -Name "AuditNTLMInDomain" -ErrorAction SilentlyContinue
    if ($AuditDomain) {
        Write-Host "[+] AuditNTLMInDomain is set to $($AuditDomain.AuditNTLMInDomain) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: AuditNTLMInDomain is not configured." -ForegroundColor Red
    }

    $RestrictDomain = Get-ItemProperty -Path $NetlogonPath -Name "RestrictNTLMInDomain" -ErrorAction SilentlyContinue
    if ($RestrictDomain) {
        Write-Host "[+] RestrictNTLMInDomain is set to $($RestrictDomain.RestrictNTLMInDomain) (Secure)." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: RestrictNTLMInDomain is not configured." -ForegroundColor Red
    }
} else {
    Write-Host "[!] Netlogon Parameters path does not exist." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-RestrictNTLM.ps1
# Description: Configures local registry values to enforce NTLM restrictions and auditing.

Write-Host "Applying hardening requirement: Restrict NTLM..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
$NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"

# Ensure LSA MSV1_0 path exists and apply settings
if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "AuditReceivingNTLMTraffic" -Value 2 -Type DWord
Set-ItemProperty -Path $LsaPath -Name "RestrictReceivingNTLMTraffic" -Value 2 -Type DWord
Set-ItemProperty -Path $LsaPath -Name "RestrictSendingNTLMTraffic" -Value 2 -Type DWord

# Ensure Netlogon Parameters path exists and apply settings
if (-not (Test-Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}

Set-ItemProperty -Path $NetlogonPath -Name "AuditNTLMInDomain" -Value 7 -Type DWord
Set-ItemProperty -Path $NetlogonPath -Name "RestrictNTLMInDomain" -Value 3 -Type DWord

Write-Host "NTLM restriction registry configurations applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2014" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-015" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-015] Migrate SYSVOL Replication to DFSR</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/migrate-sysvol-replication-dfsr.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory domain environments rely on replication to synchronize GPO templates and scripts stored in the <xhtml:code>SYSVOL</xhtml:code> share across all Domain Controllers. Historically, this replication was managed by the File Replication Service (FRS).</xhtml:p>
        <xhtml:p>However, FRS is obsolete, does not support modern transport-layer security features, and is prone to replication database corruption.</xhtml:p>
        <xhtml:p>Migrating to Distributed File System Replication (DFSR): 1. <xhtml:strong>Ensures Replication Integrity</xhtml:strong>: DFSR uses remote differential compression algorithms and hash validation to verify that files are replicated securely and without corruption. 2. <xhtml:strong>Minimizes Attack Surface</xhtml:strong>: Transitioning to DFSR allows security administrators to completely disable and deprecate the legacy, insecure FRS service and its associated RPC endpoints. 3. <xhtml:strong>Improves Diagnostics</xhtml:strong>: DFSR provides comprehensive logging, system health auditing, and diagnostic reports, allowing quick identification of synchronization failures.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Step-by-Step Migration Command Line</xhtml:h3>
        <xhtml:p>The migration process consists of transitioning the domain through four replication states (from State 0 to State 3) using the <xhtml:code>dfsrmig</xhtml:code> command line tool on a writable Domain Controller (typically the PDC Emulator).</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Verify Current State</xhtml:strong>:</xhtml:li>
          <xhtml:li>Open an elevated command prompt on the DC and run:</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /getglobalstate</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>Expected starting output</xhtml:em>: <xhtml:code>Current DFSR global state: 'Start'</xhtml:code> (State 0).</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Transition to Prepared State (State 1)</xhtml:strong>:</xhtml:li>
          <xhtml:li>This state creates a clone of the <xhtml:code>SYSVOL</xhtml:code> folder named <xhtml:code>SYSVOL_DFSR</xhtml:code> and begins DFSR replication in the background while keeping the original <xhtml:code>SYSVOL</xhtml:code> folder active via FRS.</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /setglobalstate 1</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Verify State 1 Reachability</xhtml:strong>:</xhtml:li>
          <xhtml:li>Query all Domain Controllers to ensure they have successfully transitioned to the Prepared state:</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /getmigrationstate</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>Do not proceed to the next step until the output confirms</xhtml:em>: <xhtml:code>All Domain Controllers have migrated successfully to the Global state ('Prepared')</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Transition to Redirected State (State 2)</xhtml:strong>:</xhtml:li>
          <xhtml:li>This state redirects the active <xhtml:code>SYSVOL</xhtml:code> network share mapping to point to the new <xhtml:code>SYSVOL_DFSR</xhtml:code> folder replicated by DFSR. FRS continues replication in the background for backward compatibility/rollback capability.</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /setglobalstate 2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Verify State 2 Reachability</xhtml:strong>:</xhtml:li>
          <xhtml:li>Query the status to confirm all DCs have successfully redirected:</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /getmigrationstate</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>Do not proceed until the output confirms</xhtml:em>: <xhtml:code>All Domain Controllers have migrated successfully to the Global state ('Redirected')</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Transition to Eliminated State (State 3)</xhtml:strong>:</xhtml:li>
          <xhtml:li>This final stage commits the migration. It deletes the original <xhtml:code>SYSVOL</xhtml:code> directory, stops and disables the FRS service, and deletes the FRS replication configuration from Active Directory.</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /setglobalstate 3</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Verify State 3 Committal</xhtml:strong>:</xhtml:li>
          <xhtml:li>Confirm the migration is complete:</xhtml:li>
          <xhtml:li>
            <xhtml:code>dfsrmig /getmigrationstate</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>Expected Output</xhtml:em>: <xhtml:code>All Domain Controllers have migrated successfully to the Global state ('Eliminated')</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Migration Status Auditing</xhtml:h3>
        <xhtml:p>Use this PowerShell script to monitor the progress of the DFSR migration across all Domain Controllers in the forest.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SYSVOLDfsrMigrationStatus.ps1">Download Script: Get-SYSVOLDfsrMigrationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SYSVOLDfsrMigrationStatus.ps1
# Description: Checks the current SYSVOL replication migration state.

Import-Module ActiveDirectory

Write-Host "--- Auditing SYSVOL DFSR Migration Status ---" -ForegroundColor Cyan

# Check if the FRS service is still running on this DC
$FrsService = Get-Service -Name "NtFrs" -ErrorAction SilentlyContinue

if ($null -ne $FrsService) {
    Write-Host "[*] FRS Service State: $($FrsService.Status)" -ForegroundColor White
} else {
    Write-Host "[+] FRS Service is not installed (expected in modern server configurations)." -ForegroundColor Green
}

# Run dfsrmig validation checks
$DfsMigOutput = &amp; dfsrmig.exe /getglobalstate 2&gt;&amp;1

if ($DfsMigOutput -like "*Eliminated*") {
    Write-Host "[+] SYSVOL migration to DFSR is complete and finalized (State 3: Eliminated)." -ForegroundColor Green
} else {
    Write-Host "[-] WARNING: SYSVOL replication is not fully migrated to DFSR." -ForegroundColor Red
    Write-Host "    Current Status: $DfsMigOutput" -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify active DFSR health on the server:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-DfsrHealthStatus.ps1">Download Script: Get-DfsrHealthStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DfsrHealthStatus.ps1
# Description: Checks the event logs for DFSR replication errors.

Write-Host "Checking DFSR replication event logs..." -ForegroundColor Cyan

$DfsrEvents = Get-WinEvent -LogName "DFS Replication" -MaxEvents 10 -ErrorAction SilentlyContinue

if ($DfsrEvents) {
    foreach ($DfsrEvent in $DfsrEvents) {
        $EventColor = if ($DfsrEvent.LevelDisplayName -eq "Error") { "Red" } else { "White" }
        Write-Host "[$($DfsrEvent.TimeCreated)] [$($DfsrEvent.LevelDisplayName)] ID: $($DfsrEvent.Id) - $($DfsrEvent.Message)" -ForegroundColor $EventColor
    }
} else {
    Write-Host "[+] No recent DFSR events or errors detected." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2015" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-016" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-016] Harden adminSDHolder Permissions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/harden-adminsdholder-permissions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In Active Directory, the <xhtml:code>adminSDHolder</xhtml:code> object acts as a security template for administrative accounts and groups (known as protected objects). Every hour, a background system thread (the <xhtml:code>AdminSDHolder</xhtml:code> task, also referred to as the <xhtml:code>ProtectAdminGroups</xhtml:code> task) running on the Domain Controller holding the PDC Emulator role compares the Access Control Lists (ACLs) of all protected objects against the ACL of the <xhtml:code>adminSDHolder</xhtml:code> object. If they differ, the ACL on the protected object is overwritten by the ACL on <xhtml:code>adminSDHolder</xhtml:code>, and security inheritance is disabled.</xhtml:p>
        <xhtml:p>A common misconception is that the Security Descriptor Propagator (<xhtml:code>SDProp</xhtml:code>) thread enforces this protection. In reality, <xhtml:code>SDProp</xhtml:code> is a separate background thread on all Domain Controllers whose sole job is to propagate inheritable Access Control Entries (ACEs) when an object is moved or a parent ACL is modified. The actual enforcement of the <xhtml:code>adminSDHolder</xhtml:code> template is performed exclusively by the <xhtml:code>AdminSDHolder</xhtml:code> background task.</xhtml:p>
        <xhtml:p>If an attacker gains temporary write permissions on the <xhtml:code>adminSDHolder</xhtml:code> object, they can inject a backdoor Access Control Entry (ACE) granting their account write permissions. Within an hour, the <xhtml:code>AdminSDHolder</xhtml:code> background task will apply this backdoor ACE to all protected groups (e.g., Domain Admins, Schema Admins, Enterprise Admins). Even if the administrator cleans up permissions on a Domain Admin account directly, the <xhtml:code>AdminSDHolder</xhtml:code> task will restore the backdoor ACE on its next run.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers (ADUC) Console Configuration</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>) on a Domain Controller.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>View</xhtml:strong> and click <xhtml:strong>Advanced Features</xhtml:strong> (if not already enabled).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>System\adminSDHolder</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>adminSDHolder</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Security</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Advanced</xhtml:strong>.</xhtml:li>
          <xhtml:li>Enforce inheritance blocking:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Verify that the button at the bottom reads </xhtml:em>
            <xhtml:em>Enable Inheritance</xhtml:em>
            <xhtml:em>. If it reads </xhtml:em>
            <xhtml:em>Disable Inheritance</xhtml:em>*, click it to block inheritance.</xhtml:li>
          <xhtml:li>* When prompted, choose to convert inherited permissions into explicit permissions to avoid losing default settings, then prune any non-compliant explicit permissions.</xhtml:li>
          <xhtml:li>Review the permission entries:</xhtml:li>
          <xhtml:li>* Ensure only highly privileged built-in groups (e.g., <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>SYSTEM</xhtml:code>) have Write, Modify, or Full Control permissions.</xhtml:li>
          <xhtml:li>* Remove any entries granting permissions to non-Tier 0 accounts, such as delegated helpdesk groups, <xhtml:code>Account Operators</xhtml:code>, <xhtml:code>Print Operators</xhtml:code>, or custom service accounts.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save changes.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to audit and remediate unauthorized permissions on the <xhtml:code>adminSDHolder</xhtml:code> object.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Harden-AdminSDHolder.ps1">Download Script: Harden-AdminSDHolder.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Harden-AdminSDHolder.ps1
# Description: Hardens the adminSDHolder ACL by auditing permissions, blocking inheritance, and removing delegated helpdesk groups.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Harden adminSDHolder Permissions..." -ForegroundColor Cyan

# Set target DN
$DomainDN = (Get-ADRootDSE).defaultNamingContext
$AdminSDPath = "AD:\CN=adminSDHolder,CN=System,$($DomainDN)"

# Define allowed high-privilege built-in identities (SIDs or names)
$AllowedTrustees = @(
    "SYSTEM",
    "Domain Admins",
    "Enterprise Admins",
    "Administrators"
)

# Fetch ACL
$Acl = Get-Acl -Path $AdminSDPath
$AclModified = $false

# 1. Enforce inheritance blocking (DACL_Protected flag)
if ($Acl.AreAccessRulesProtected) {
    Write-Host "[+] Inheritance is already blocked (protected) on the adminSDHolder container." -ForegroundColor Green
} else {
    Write-Host "[-] adminSDHolder container has inheritance enabled. Blocking inheritance..." -ForegroundColor Yellow
    # Block inheritance ($true) and copy existing rules as explicit ($true)
    $Acl.SetAccessRuleProtection($true, $true)
    $AclModified = $true
}

# 2. Prune non-compliant permissions
foreach ($Rule in $Acl.Access) {
    $Identity = $Rule.IdentityReference.Value
    
    # Check if trustee is allowed to write
    if ($Rule.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner|GenericAll|GenericWrite") {
        $IsAllowed = $false
        foreach ($Allowed in $AllowedTrustees) {
            if ($Identity -match $Allowed) {
                $IsAllowed = $true
                break
            }
        }
        
        if (-not $IsAllowed) {
            Write-Host "[-] Unauthorized write permission found: Account '$($Identity)' has rights: $($Rule.ActiveDirectoryRights)" -ForegroundColor Yellow
            
            # Remove rule
            $Acl.RemoveAccessRule($Rule) | Out-Null
            $AclModified = $true
        }
    }
}

if ($AclModified) {
    Set-Acl -Path $AdminSDPath -AclObject $Acl -ErrorAction Stop
    Write-Host "[+] adminSDHolder ACL hardened successfully." -ForegroundColor Green
} else {
    Write-Host "[+] adminSDHolder ACL is already clean." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify current adminSDHolder permissions:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AdminSDHolderAudit.ps1">Download Script: Get-AdminSDHolderAudit.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AdminSDHolderAudit.ps1
# Description: Audits and prints all active permission entries and the inheritance block status on adminSDHolder.

Import-Module ActiveDirectory

Write-Host "--- Auditing adminSDHolder Permissions ---" -ForegroundColor Cyan

$DomainDN = (Get-ADRootDSE).defaultNamingContext
$AdminSDPath = "AD:\CN=adminSDHolder,CN=System,$($DomainDN)"
$Acl = Get-Acl -Path $AdminSDPath

# Check inheritance block status
if ($Acl.AreAccessRulesProtected) {
    Write-Host "[+] Inheritance is BLOCKED (Protected) on the adminSDHolder container (Secure)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Inheritance is ENABLED (Unprotected) on the adminSDHolder container. Permissions may inherit from parent objects." -ForegroundColor Red
}

foreach ($Rule in $Acl.Access) {
    $Identity = $Rule.IdentityReference.Value
    $Rights = $Rule.ActiveDirectoryRights
    $Inheritance = $Rule.InheritanceType
    
    $Color = if ($Rights -match "WriteProperty|WriteDacl|WriteOwner|GenericAll") { "Yellow" } else { "Gray" }
    
    Write-Host "[*] Trustee: $($Identity)" -ForegroundColor White
    Write-Host "    - Rights: $($Rights)" -ForegroundColor $Color
    Write-Host "    - Inheritance: $($Inheritance)" -ForegroundColor Gray
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Harden-AdminSDHolder.ps1
# Description: Hardens the adminSDHolder ACL by auditing permissions, blocking inheritance, and removing delegated helpdesk groups.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Harden adminSDHolder Permissions..." -ForegroundColor Cyan

# Set target DN
$DomainDN = (Get-ADRootDSE).defaultNamingContext
$AdminSDPath = "AD:\CN=adminSDHolder,CN=System,$($DomainDN)"

# Define allowed high-privilege built-in identities (SIDs or names)
$AllowedTrustees = @(
    "SYSTEM",
    "Domain Admins",
    "Enterprise Admins",
    "Administrators"
)

# Fetch ACL
$Acl = Get-Acl -Path $AdminSDPath
$AclModified = $false

# 1. Enforce inheritance blocking (DACL_Protected flag)
if ($Acl.AreAccessRulesProtected) {
    Write-Host "[+] Inheritance is already blocked (protected) on the adminSDHolder container." -ForegroundColor Green
} else {
    Write-Host "[-] adminSDHolder container has inheritance enabled. Blocking inheritance..." -ForegroundColor Yellow
    # Block inheritance ($true) and copy existing rules as explicit ($true)
    $Acl.SetAccessRuleProtection($true, $true)
    $AclModified = $true
}

# 2. Prune non-compliant permissions
foreach ($Rule in $Acl.Access) {
    $Identity = $Rule.IdentityReference.Value
    
    # Check if trustee is allowed to write
    if ($Rule.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner|GenericAll|GenericWrite") {
        $IsAllowed = $false
        foreach ($Allowed in $AllowedTrustees) {
            if ($Identity -match $Allowed) {
                $IsAllowed = $true
                break
            }
        }
        
        if (-not $IsAllowed) {
            Write-Host "[-] Unauthorized write permission found: Account '$($Identity)' has rights: $($Rule.ActiveDirectoryRights)" -ForegroundColor Yellow
            
            # Remove rule
            $Acl.RemoveAccessRule($Rule) | Out-Null
            $AclModified = $true
        }
    }
}

if ($AclModified) {
    Set-Acl -Path $AdminSDPath -AclObject $Acl -ErrorAction Stop
    Write-Host "[+] adminSDHolder ACL hardened successfully." -ForegroundColor Green
} else {
    Write-Host "[+] adminSDHolder ACL is already clean." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2016" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-017" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-017] Harden Microsoft DNS AD Container Permissions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/harden-dns-container-permissions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In Active Directory-integrated DNS environments, DNS configuration settings, zones, and resource records are stored directly within the directory and managed via the Microsoft DNS Server service. By default, the built-in <xhtml:code>DnsAdmins</xhtml:code> group possesses management rights over the DNS service, while standard authenticated domain users possess rights to register new DNS records in AD-integrated zones.</xhtml:p>
        <xhtml:p>This configuration exposes Domain Controllers and Active Directory to critical attack vectors: 1. <xhtml:strong>DNS Service DLL Hijacking (`ServerLevelPluginDll`)</xhtml:strong>: The Microsoft DNS Server management RPC interface permits members of <xhtml:code>DnsAdmins</xhtml:code> (and accounts with write control over the DNS server configuration) to set the <xhtml:code>ServerLevelPluginDll</xhtml:code> parameter using <xhtml:code>dnscmd.exe /config /serverlevelplugindll \\path\to\malicious.dll</xhtml:code>. Because the DNS Server service runs as <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code> on Domain Controllers, the service loads this DLL upon restart or server reboot, executing arbitrary code with SYSTEM privileges and granting full Domain Controller compromise (effectively making <xhtml:code>DnsAdmins</xhtml:code> a Tier 0 equivalent group). 2. <xhtml:strong>ADIDNS Record Spoofing &amp; Kerberos Reflection (Ghost-SPN)</xhtml:strong>: In Active Directory Integrated DNS (ADIDNS) zones, the root container DACL grants <xhtml:code>Authenticated Users</xhtml:code> the <xhtml:code>Create all child objects</xhtml:code> right (specifically <xhtml:code>Create dnsNode objects</xhtml:code>) by default. This allows any standard domain user or compromised workstation account to register arbitrary DNS records. Attackers exploit this capability to register Unicode homoglyphs (such as <xhtml:code>․</xhtml:code> U+2024 or <xhtml:code>Ⓡ</xhtml:code> U+00AE) matching high-value servers or Domain Controllers. When clients request Kerberos service tickets (TGS-REQ) for an SPN like <xhtml:code>HOST/target</xhtml:code>, Kerberos linguistic normalization canonicalizes the homoglyph SPN to ASCII (matching the legitimate target), while the Windows DNS client resolves the IP via the attacker's ADIDNS homoglyph record, allowing Kerberos AP-REQ reflection attacks (CVE-2025-58726 / Synacktiv research) and WPAD hijacking. 3. <xhtml:strong>Partition Directory DACL Tampering</xhtml:strong>: Modern AD environments store DNS zones across dedicated Application Directory Partitions (<xhtml:code>DomainDnsZones</xhtml:code> and <xhtml:code>ForestDnsZones</xhtml:code>) as well as the legacy <xhtml:code>CN=System</xhtml:code> container. Write access on these containers allows non-Tier 0 identities to modify zone delegations, poison records, manipulate SOA/NS records, or grant themselves persistent backdoor rights.</xhtml:p>
        <xhtml:p>Enforcing GPO-based restriction on <xhtml:code>DnsAdmins</xhtml:code>, purging <xhtml:code>ServerLevelPluginDll</xhtml:code>, enforcing Secure Dynamic Updates, and removing arbitrary child record creation rights on ADIDNS zones ensures that the directory DNS infrastructure strictly adheres to the Tier 0 administrative boundary.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) &amp; Active Directory Console Configuration</xhtml:h3>
        <xhtml:h4>1. Enforce DnsAdmins Group Hygiene via GPO Restricted Groups</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Group Policy Management</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the baseline GPO applied to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Restricted Groups</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Restricted Groups</xhtml:strong> and select <xhtml:strong>Add Group...</xhtml:strong>.</xhtml:li>
          <xhtml:li>Type <xhtml:code>DnsAdmins</xhtml:code> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Members of this group</xhtml:strong>, leave the member list <xhtml:strong>empty</xhtml:strong> (or populate it strictly with verified Tier 0 accounts such as <xhtml:code>Domain Admins</xhtml:code>).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Prevent DNS DLL Hijacking via GPO Preferences Registry Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Delete</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\DNS\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>ServerLevelPluginDll</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Enforce Secure Dynamic Updates on All AD-Integrated Zones</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>DNS Manager</xhtml:strong> console (<xhtml:code>dnsmgmt.msc</xhtml:code>) on a Domain Controller.</xhtml:li>
          <xhtml:li>Expand the Domain Controller node -&gt; <xhtml:strong>Forward Lookup Zones</xhtml:strong>.</xhtml:li>
          <xhtml:li>Right-click each AD-integrated zone and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>On the <xhtml:strong>General</xhtml:strong> tab, set <xhtml:strong>Dynamic updates</xhtml:strong> to <xhtml:strong>Secure only</xhtml:strong>.</xhtml:li>
          <xhtml:li>Repeat this configuration for all Forward and Reverse Lookup Zones.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Restrict Arbitrary Record Creation &amp; Ghost-SPN on ADIDNS Zones</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In <xhtml:strong>DNS Manager</xhtml:strong>, right-click the domain DNS zone and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Security</xhtml:strong> tab, then click <xhtml:strong>Advanced</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the entry for <xhtml:strong>Authenticated Users</xhtml:strong> and click <xhtml:strong>Edit</xhtml:strong>.</xhtml:li>
          <xhtml:li>Clear the <xhtml:strong>Create all child objects</xhtml:strong> (or <xhtml:strong>Create dnsNode objects</xhtml:strong>) permission to prevent standard domain users from creating arbitrary DNS records or Unicode homoglyphs.</xhtml:li>
          <xhtml:li>Ensure machine accounts retain permissions to register their own hostname records, or utilize DHCP servers with dedicated service account credentials for dynamic updates.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to apply.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>5. Audit &amp; Restrict Permissions on MicrosoftDNS Containers</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>) with <xhtml:strong>View</xhtml:strong> -&gt; <xhtml:strong>Advanced Features</xhtml:strong> enabled.</xhtml:li>
          <xhtml:li>Check permissions on <xhtml:code>System\MicrosoftDNS</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>MicrosoftDNS</xhtml:em>
            <xhtml:em> -&gt; </xhtml:em>
            <xhtml:em>Properties</xhtml:em>
            <xhtml:em> -&gt; </xhtml:em>
            <xhtml:em>Security</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Verify that non-Tier 0 identities and `DnsAdmins` do not hold </xhtml:em>
            <xhtml:em>Write all properties</xhtml:em>
            <xhtml:em>, </xhtml:em>
            <xhtml:em>Modify permissions</xhtml:em>
            <xhtml:em>, or </xhtml:em>
            <xhtml:em>Full Control</xhtml:em>*.</xhtml:li>
          <xhtml:li>To inspect Application Partitions (<xhtml:code>DomainDnsZones</xhtml:code> and <xhtml:code>ForestDnsZones</xhtml:code>):</xhtml:li>
          <xhtml:li>
            <xhtml:em> Open </xhtml:em>
            <xhtml:em>ADSI Edit</xhtml:em>* (<xhtml:code>adsiedit.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>* Connect to Naming Context: <xhtml:code>DC=DomainDnsZones,DC=[Domain]</xhtml:code> and navigate to <xhtml:code>CN=MicrosoftDNS</xhtml:code>.</xhtml:li>
          <xhtml:li>* Connect to Naming Context: <xhtml:code>DC=ForestDnsZones,DC=[ForestRootDomain]</xhtml:code> and navigate to <xhtml:code>CN=MicrosoftDNS</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>MicrosoftDNS</xhtml:em>
            <xhtml:em> -&gt; </xhtml:em>
            <xhtml:em>Properties</xhtml:em>
            <xhtml:em> -&gt; </xhtml:em>
            <xhtml:em>Security</xhtml:em>
            <xhtml:em> -&gt; </xhtml:em>
            <xhtml:em>Advanced</xhtml:em>* and verify that only Tier 0 accounts possess write access.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to remove the <xhtml:code>ServerLevelPluginDll</xhtml:code> backdoor, enforce Secure Dynamic Updates on all AD-integrated zones, and audit <xhtml:code>DnsAdmins</xhtml:code> membership.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Harden-DnsServerConfiguration.ps1">Download Script: Harden-DnsServerConfiguration.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Harden-DnsServerConfiguration.ps1
# Description: Hardens Microsoft DNS on Domain Controllers by removing ServerLevelPluginDll backdoors, enforcing Secure Dynamic Updates on AD-integrated zones, and verifying DnsAdmins membership.

Import-Module ActiveDirectory -ErrorAction SilentlyContinue
Import-Module DnsServer -ErrorAction SilentlyContinue

Write-Host "Applying hardening requirement: Harden Microsoft DNS AD Container..." -ForegroundColor Cyan

# 1. Clean up ServerLevelPluginDll Registry Key
$RegPath = "HKLM:\System\CurrentControlSet\Services\DNS\Parameters"
$ValueName = "ServerLevelPluginDll"

if (Test-Path -Path $RegPath) {
    $PluginDll = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $PluginDll -and $null -ne $PluginDll.ServerLevelPluginDll -and $PluginDll.ServerLevelPluginDll -ne "") {
        Write-Host "[-] WARNING: Potentially unauthorized DNS plugin detected: $($PluginDll.ServerLevelPluginDll)" -ForegroundColor Yellow
        Remove-ItemProperty -Path $RegPath -Name $ValueName -Force -ErrorAction Stop
        Write-Host "[+] ServerLevelPluginDll registry parameter removed successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] No ServerLevelPluginDll registry parameter found (clean configuration)." -ForegroundColor Green
    }
}

# 2. Enforce Secure Dynamic Updates on Active Directory-Integrated Zones
if (Get-Command -Name "Get-DnsServerZone" -ErrorAction SilentlyContinue) {
    Write-Host "Checking Dynamic Update settings on AD-integrated DNS zones..." -ForegroundColor White
    $Zones = Get-DnsServerZone -ErrorAction SilentlyContinue | Where-Object { $_.IsDsIntegrated -eq $true -and $_.ZoneType -eq "Primary" }
    foreach ($Zone in $Zones) {
        if ($Zone.DynamicUpdate -ne "Secure") {
            Write-Host "[-] Zone '$($Zone.ZoneName)' has DynamicUpdate set to '$($Zone.DynamicUpdate)'. Enforcing Secure only..." -ForegroundColor Yellow
            Set-DnsServerPrimaryZone -Name $Zone.ZoneName -DynamicUpdate "Secure" -ErrorAction SilentlyContinue
            Write-Host "[+] Zone '$($Zone.ZoneName)' DynamicUpdate set to Secure." -ForegroundColor Green
        } else {
            Write-Host "[+] Zone '$($Zone.ZoneName)' DynamicUpdate is Secure." -ForegroundColor Green
        }
    }
}

# 3. Audit and Alert on DnsAdmins Membership
if (Get-Command -Name "Get-ADGroup" -ErrorAction SilentlyContinue) {
    $DnsAdminsGroup = Get-ADGroup -Filter "Name -eq 'DnsAdmins'" -ErrorAction SilentlyContinue

    if ($null -ne $DnsAdminsGroup) {
        $Members = Get-ADGroupMember -Identity $DnsAdminsGroup -ErrorAction SilentlyContinue
        if ($null -ne $Members -and @($Members).Count -gt 0) {
            Write-Host "[-] WARNING: The DnsAdmins group contains active members. Ensure all members are verified Tier 0 identities:" -ForegroundColor Yellow
            foreach ($Member in $Members) {
                Write-Host "    - Member: $($Member.SamAccountName) ($($Member.objectClass))" -ForegroundColor White
            }
        } else {
            Write-Host "[+] The DnsAdmins group is empty (recommended Tier 0 posture)." -ForegroundColor Green
        }
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit active DNS parameters, AD container permissions, dynamic updates, and homoglyph records:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DnsAuditStatus.ps1">Download Script: Get-DnsAuditStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DnsAuditStatus.ps1
# Description: Queries the DNS registry parameter settings, AD container ACLs, dynamic updates, and homoglyph records.

Import-Module ActiveDirectory -ErrorAction SilentlyContinue
Import-Module DnsServer -ErrorAction SilentlyContinue

Write-Host "--- Auditing DNS Security Parameters ---" -ForegroundColor Cyan

$isVulnerable = $false

# 1. Check ServerLevelPluginDll Registry Backdoor
$RegPath = "HKLM:\System\CurrentControlSet\Services\DNS\Parameters"
$ValueName = "ServerLevelPluginDll"

if (Test-Path -Path $RegPath) {
    $Val = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Val -and $null -ne $Val.ServerLevelPluginDll -and $Val.ServerLevelPluginDll -ne "") {
        Write-Host "[!] VULNERABLE: ServerLevelPluginDll is configured: $($Val.ServerLevelPluginDll)" -ForegroundColor Red
        $isVulnerable = $true
    } else {
        Write-Host "[+] ServerLevelPluginDll: Not configured (Secure)." -ForegroundColor Green
    }
}

# 2. Check DnsAdmins Membership
if (Get-Command -Name "Get-ADGroup" -ErrorAction SilentlyContinue) {
    $DnsAdminsGroup = Get-ADGroup -Filter "Name -eq 'DnsAdmins'" -ErrorAction SilentlyContinue
    if ($null -ne $DnsAdminsGroup) {
        $Members = Get-ADGroupMember -Identity $DnsAdminsGroup -ErrorAction SilentlyContinue
        if ($null -ne $Members -and @($Members).Count -gt 0) {
            Write-Host "[-] WARNING: DnsAdmins group contains active members (Verify Tier 0 boundary):" -ForegroundColor Yellow
            foreach ($Member in $Members) {
                Write-Host "    - Member: $($Member.SamAccountName)" -ForegroundColor Yellow
            }
        } else {
            Write-Host "[+] DnsAdmins group is empty (Secure)." -ForegroundColor Green
        }
    }
}

# 3. Check Dynamic Updates on AD-Integrated Zones
if (Get-Command -Name "Get-DnsServerZone" -ErrorAction SilentlyContinue) {
    $Zones = Get-DnsServerZone -ErrorAction SilentlyContinue | Where-Object { $_.IsDsIntegrated -eq $true -and $_.ZoneType -eq "Primary" }
    foreach ($Zone in $Zones) {
        if ($Zone.DynamicUpdate -ne "Secure") {
            Write-Host "[!] VULNERABLE: Zone '$($Zone.ZoneName)' DynamicUpdate is set to '$($Zone.DynamicUpdate)' (Expected: Secure)." -ForegroundColor Red
            $isVulnerable = $true
        } else {
            Write-Host "[+] Zone '$($Zone.ZoneName)': DynamicUpdate is Secure." -ForegroundColor Green
        }
    }
}

# 4. Check AD Container Write ACLs (System, DomainDnsZones, ForestDnsZones)
if (Get-Command -Name "Get-ADRootDSE" -ErrorAction SilentlyContinue) {
    $RootDSE = Get-ADRootDSE -ErrorAction SilentlyContinue
    if ($null -ne $RootDSE) {
        $DomainDN = $RootDSE.defaultNamingContext
        $RootDomainDN = $RootDSE.rootDomainNamingContext

        $Containers = @(
            "AD:\CN=MicrosoftDNS,CN=System,$DomainDN",
            "AD:\CN=MicrosoftDNS,DC=DomainDnsZones,$DomainDN",
            "AD:\CN=MicrosoftDNS,DC=ForestDnsZones,$RootDomainDN"
        )

        $AllowedTrustees = @(
            "NT AUTHORITY\SYSTEM",
            "BUILTIN\Administrators",
            "Enterprise Domain Controllers",
            "Domain Admins",
            "Enterprise Admins"
        )

        foreach ($ContainerPath in $Containers) {
            if (Test-Path -Path $ContainerPath) {
                Write-Host "Reviewing AD container permissions: $($ContainerPath)..." -ForegroundColor White
                $Acl = Get-Acl -Path $ContainerPath -ErrorAction SilentlyContinue
                if ($null -ne $Acl) {
                    foreach ($Rule in $Acl.Access) {
                        $Identity = $Rule.IdentityReference.Value
                        $Rights = $Rule.ActiveDirectoryRights

                        if ($Rights -match "WriteProperty|WriteDacl|WriteOwner|GenericAll|GenericWrite") {
                            $IsAllowed = $false
                            foreach ($Allowed in $AllowedTrustees) {
                                if ($Identity -match [regex]::Escape($Allowed)) {
                                    $IsAllowed = $true
                                    break
                                }
                            }

                            if (-not $IsAllowed) {
                                Write-Host "[!] VULNERABLE: Unauthorized write permission on $($ContainerPath) - Trustee: $($Identity) - Rights: $($Rights)" -ForegroundColor Red
                                $isVulnerable = $true
                            }
                        }
                    }
                }
            }
        }
    }
}

# 5. Check for Non-ASCII / Unicode Homoglyph Records (Ghost-SPN / CVE-2025-58726)
if (Get-Command -Name "Get-DnsServerResourceRecord" -ErrorAction SilentlyContinue) {
    $Zones = Get-DnsServerZone -ErrorAction SilentlyContinue | Where-Object { $_.IsDsIntegrated -eq $true -and $_.ZoneType -eq "Primary" }
    foreach ($Zone in $Zones) {
        $Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ErrorAction SilentlyContinue
        if ($null -ne $Records) {
            foreach ($Record in $Records) {
                if ($Record.HostName -match "[^\x20-\x7E]") {
                    Write-Host "[!] VULNERABLE: Potential Ghost-SPN homoglyph record detected in zone '$($Zone.ZoneName)': $($Record.HostName)" -ForegroundColor Red
                    $isVulnerable = $true
                }
            }
        }
    }
}

# Final Compliance Verdict
if ($isVulnerable) {
    Write-Host "[!] Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "[+] Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Harden-DnsServerConfiguration.ps1
# Description: Hardens Microsoft DNS on Domain Controllers by removing ServerLevelPluginDll backdoors, enforcing Secure Dynamic Updates on AD-integrated zones, and verifying DnsAdmins membership.

Import-Module ActiveDirectory -ErrorAction SilentlyContinue
Import-Module DnsServer -ErrorAction SilentlyContinue

Write-Host "Applying hardening requirement: Harden Microsoft DNS AD Container..." -ForegroundColor Cyan

# 1. Clean up ServerLevelPluginDll Registry Key
$RegPath = "HKLM:\System\CurrentControlSet\Services\DNS\Parameters"
$ValueName = "ServerLevelPluginDll"

if (Test-Path -Path $RegPath) {
    $PluginDll = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $PluginDll -and $null -ne $PluginDll.ServerLevelPluginDll -and $PluginDll.ServerLevelPluginDll -ne "") {
        Write-Host "[-] WARNING: Potentially unauthorized DNS plugin detected: $($PluginDll.ServerLevelPluginDll)" -ForegroundColor Yellow
        Remove-ItemProperty -Path $RegPath -Name $ValueName -Force -ErrorAction Stop
        Write-Host "[+] ServerLevelPluginDll registry parameter removed successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] No ServerLevelPluginDll registry parameter found (clean configuration)." -ForegroundColor Green
    }
}

# 2. Enforce Secure Dynamic Updates on Active Directory-Integrated Zones
if (Get-Command -Name "Get-DnsServerZone" -ErrorAction SilentlyContinue) {
    Write-Host "Checking Dynamic Update settings on AD-integrated DNS zones..." -ForegroundColor White
    $Zones = Get-DnsServerZone -ErrorAction SilentlyContinue | Where-Object { $_.IsDsIntegrated -eq $true -and $_.ZoneType -eq "Primary" }
    foreach ($Zone in $Zones) {
        if ($Zone.DynamicUpdate -ne "Secure") {
            Write-Host "[-] Zone '$($Zone.ZoneName)' has DynamicUpdate set to '$($Zone.DynamicUpdate)'. Enforcing Secure only..." -ForegroundColor Yellow
            Set-DnsServerPrimaryZone -Name $Zone.ZoneName -DynamicUpdate "Secure" -ErrorAction SilentlyContinue
            Write-Host "[+] Zone '$($Zone.ZoneName)' DynamicUpdate set to Secure." -ForegroundColor Green
        } else {
            Write-Host "[+] Zone '$($Zone.ZoneName)' DynamicUpdate is Secure." -ForegroundColor Green
        }
    }
}

# 3. Audit and Alert on DnsAdmins Membership
if (Get-Command -Name "Get-ADGroup" -ErrorAction SilentlyContinue) {
    $DnsAdminsGroup = Get-ADGroup -Filter "Name -eq 'DnsAdmins'" -ErrorAction SilentlyContinue

    if ($null -ne $DnsAdminsGroup) {
        $Members = Get-ADGroupMember -Identity $DnsAdminsGroup -ErrorAction SilentlyContinue
        if ($null -ne $Members -and @($Members).Count -gt 0) {
            Write-Host "[-] WARNING: The DnsAdmins group contains active members. Ensure all members are verified Tier 0 identities:" -ForegroundColor Yellow
            foreach ($Member in $Members) {
                Write-Host "    - Member: $($Member.SamAccountName) ($($Member.objectClass))" -ForegroundColor White
            }
        } else {
            Write-Host "[+] The DnsAdmins group is empty (recommended Tier 0 posture)." -ForegroundColor Green
        }
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2017" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-018" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-018] Harden Virtualization Hosts for Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Virtualization Hosts (Hyper-V / VMware ESXi hosting Domain Controllers)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, VMware vSphere ESXi 6.7+</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/harden-dc-virtualization-hosts.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In modern IT environments, Domain Controllers (DCs) are frequently virtualized. However, a virtualized DC is only as secure as the physical host and hypervisor running it.</xhtml:p>
        <xhtml:p>If a hypervisor hosting a DC is compromised, an attacker can: 1. <xhtml:strong>Harvest NTDS.dit Offline</xhtml:strong>: Copy the virtual hard disk file (VHDX/VMDK) of the running DC and extract all domain password hashes offline. 2. <xhtml:strong>Manipulate Memory</xhtml:strong>: Dump the guest DC's LSASS memory directly from the hypervisor console, exposing active Tier 0 administrator credentials. 3. <xhtml:strong>Inject Arbitrary Commands</xhtml:strong>: Use integration tools (like Hyper-V Integration Services or VMware Tools) to run code within the guest OS without authenticating.</xhtml:p>
        <xhtml:p>To mitigate these risks: <xhtml:em> </xhtml:em>
          <xhtml:em>Host Segregation</xhtml:em>
          <xhtml:em>: Hypervisors hosting Tier 0 Domain Controllers must be dedicated exclusively to Tier 0 workloads. Lower-tier virtual machines (Tier 1/2) must never run on the same physical host clusters. </xhtml:em>
          <xhtml:strong>Administrative Isolation</xhtml:strong>: The virtualization hosts and management consoles (e.g., vCenter, Hyper-V Manager) must be managed exclusively by Tier 0 administrative accounts. <xhtml:em> </xhtml:em>
          <xhtml:em>Virtual Machine Security</xhtml:em>*: Enable shielded VMs or VM encryption options to cryptographically lock the guest OS resources and protect virtual disks from unauthorized access.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Virtualization Host Isolation (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Identify all physical hosts running virtualized Domain Controllers.</xhtml:li>
          <xhtml:li>Move all non-Tier 0 virtual machines off these hosts using live migration (vMotion/Live Migration).</xhtml:li>
          <xhtml:li>Place these hosts into a dedicated, isolated hypervisor cluster (e.g., <xhtml:code>Cluster-Tier0</xhtml:code>).</xhtml:li>
          <xhtml:li>Reconfigure management permissions on the virtualization console:</xhtml:li>
          <xhtml:li>* Remove standard admin permissions from the cluster.</xhtml:li>
          <xhtml:li>* Restrict access rights exclusively to a dedicated Tier 0 virtualization administrator group.</xhtml:li>
          <xhtml:li>Disable unnecessary virtual integration services in the VM settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> In Hyper-V Manager, open DC VM Properties -&gt; </xhtml:em>
            <xhtml:em>Integration Services</xhtml:em>
            <xhtml:em> -&gt; Uncheck </xhtml:em>
            <xhtml:em>Guest services</xhtml:em>
            <xhtml:em> and </xhtml:em>
            <xhtml:em>Time synchronization</xhtml:em>* (if relying on NTP domain hierarchy).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Host Configuration Auditing</xhtml:h3>
        <xhtml:p>Run the following script block on a Domain Controller to determine if it is virtualized, identify the hypervisor type, and audit key integration parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DcVirtualizationStatus.ps1">Download Script: Get-DcVirtualizationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DcVirtualizationStatus.ps1
# Description: Audits the virtualization environment of the Domain Controller.

Write-Host "--- Auditing DC Virtualization Status ---" -ForegroundColor Cyan

# 1. Determine if running on physical or virtual hardware
$ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
$Model = $ComputerSystem.Model
$Manufacturer = $ComputerSystem.Manufacturer

Write-Host "[*] Host Manufacturer: $($Manufacturer)" -ForegroundColor White
Write-Host "[*] System Model:       $($Model)" -ForegroundColor White

$IsVirtual = $false
$HypervisorType = "Unknown"

if ($Model -match "Virtual Machine|VMware|VirtualBox|Xen") {
    $IsVirtual = $true
    if ($Manufacturer -match "Microsoft") { $HypervisorType = "Hyper-V" }
    elseif ($Manufacturer -match "VMware") { $HypervisorType = "VMware ESXi" }
}

if ($IsVirtual) {
    Write-Host "[-] WARNING: Domain Controller is virtualized on $($HypervisorType)." -ForegroundColor Yellow
    Write-Host "    Ensure the underlying host is secured as a Tier 0 asset." -ForegroundColor Yellow
    
    # 2. Check VM integration service settings if Hyper-V guest
    if ($HypervisorType -eq "Hyper-V") {
        $IntegrationServices = Get-Service -Name "vm*" -ErrorAction SilentlyContinue
        if ($IntegrationServices) {
            Write-Host "    Integration Services detected:" -ForegroundColor White
            foreach ($Svc in $IntegrationServices) {
                Write-Host "    - $($Svc.Name): $($Svc.Status)" -ForegroundColor White
            }
        }
    }
} else {
    Write-Host "[+] Domain Controller is running on physical hardware (secure boundary)." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2018" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-019" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-019] Enforce RDP Restricted Admin Mode</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients, PAWs</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enforce-rdp-restricted-admin.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Remote Desktop Protocol (RDP) is a standard tool for administrative sessions. However, by default, RDP authenticates users by placing their credentials (NTLM hashes or Kerberos tickets) directly in the Local Security Authority Subsystem Service (LSASS) memory of the destination host.</xhtml:p>
        <xhtml:p>If an administrator connects to a compromised host (such as a Tier 1 server or Tier 2 workstation) from their workstation using standard RDP, an attacker with local administrator privileges on that target system can dump LSASS and harvest the administrator's credentials. This allows the attacker to compromise the administrator's account and move laterally or escalate privileges.</xhtml:p>
        <xhtml:p>Enforcing RDP Restricted Admin Mode (RDP RA) prevents credential harvesting: 1. <xhtml:strong>Blocks Credential Transmission</xhtml:strong>: Under Restricted Admin mode, the client does not send the user's plaintext password, NTLM hash, or Kerberos TGT to the remote host. The host validates the connection without caching reusable credentials in its LSASS database. 2. <xhtml:strong>Limits Remote Session Privilege</xhtml:strong>: In network access attempts initiated from within the RDP session, the remote session runs in the security context of the destination machine's computer account (<xhtml:code>$MachineName$</xhtml:code>) rather than the administrator's user account.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration</xhtml:h3>
        <xhtml:h4>1. Enforce Client-Side Connection Restriction (PAWs &amp; Workstations)</xhtml:h4>
        <xhtml:p>To force administrative workstations to use Restricted Admin mode for all remote RDP sessions:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting administrative hosts (e.g., <xhtml:code>GPO_Workstation_Hardening</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Credentials Delegation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click the <xhtml:strong>Restrict delegation of credentials to remote servers</xhtml:strong> policy.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the options dropdown, select <xhtml:strong>Require Restricted Admin</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> and link the GPO to your PAW / Workstation OUs.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Server-Side Support (Domain Controllers &amp; Member Servers)</xhtml:h4>
        <xhtml:p>Ensure that all target hosts are configured to permit Restricted Admin connections:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting servers (e.g., <xhtml:code>GPO_Server_Hardening</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Credentials Delegation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Restrict delegation of credentials to remote servers</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Require Remote Credential Guard or Restricted Admin</xhtml:strong> (or <xhtml:strong>Require Restricted Admin</xhtml:strong>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Connection Client</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Do not allow passwords to be saved</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>8b. Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>8c. Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Restrict Remote Desktop Services users to a single Remote Desktop Services session</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow drive redirection` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow COM port redirection` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow LPT port redirection` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow supported Plug and Play device redirection` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Always prompt for password upon connection` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Require secure RPC communication` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Set client connection encryption level` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>High Level</xhtml:code> in the options dropdown)</xhtml:li>
          <xhtml:li>12b. Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Session Time Limits</xhtml:code>
          </xhtml:li>
          <xhtml:li>12c. Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Set time limit for active but idle Remote Desktop Services sessions` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>15 minutes</xhtml:code> in the options dropdown)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Set time limit for disconnected sessions` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>1 minute</xhtml:code> in the options dropdown)</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> and link the GPO to your Domain Controllers and Member Servers OUs.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to configure the local host registry to allow and enforce Restricted Admin mode.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-RdpRestrictedAdmin.ps1">Download Script: Set-RdpRestrictedAdmin.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-RdpRestrictedAdmin.ps1
# Description: Enables RDP Restricted Admin mode support and hardens RDP session options.

Write-Host "Applying hardening requirement: Enforce RDP Restricted Admin Mode and Session Controls..." -ForegroundColor Cyan

# 1. Enable Restricted Admin support
$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DisableRestrictedAdmin"
$ValueData = 0

if (Test-Path $LsaPath) {
    Set-ItemProperty -Path $LsaPath -Name $ValueName -Value $ValueData -Type DWord -ErrorAction Stop
    Write-Host "[+] Local system configured to accept RDP Restricted Admin connections." -ForegroundColor Green
} else {
    Write-Warning "LSA Registry path not found."
}

# 2. Harden RDP Session options in registry
$RdpPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $RdpPolicyPath)) {
    New-Item -Path $RdpPolicyPath -Force | Out-Null
}

$RdpSettings = @{
    "DisablePasswordSaving" = 1
    "fSingleSessionPerUser" = 1
    "fDisableCdm"           = 1
    "fDisableCcm"           = 1
    "fDisableLpt"           = 1
    "fDisablePNPRedir"      = 1
    "fPromptForPassword"    = 1
    "fEncryptRPCTraffic"    = 1
    "MinEncryptionLevel"    = 3
    "MaxIdleTime"           = 900000
    "MaxDisconnectionTime"  = 60000
}

foreach ($Setting in $RdpSettings.Keys) {
    Set-ItemProperty -Path $RdpPolicyPath -Name $Setting -Value $RdpSettings[$Setting] -Type DWord -ErrorAction Stop
}
Write-Host "[+] RDP session security controls applied to registry." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the local RDP configuration status:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-RdpRestrictedAdminStatus.ps1">Download Script: Get-RdpRestrictedAdminStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-RdpRestrictedAdminStatus.ps1
# Description: Checks the configuration state of RDP Restricted Admin and session security settings.

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DisableRestrictedAdmin"

Write-Host "Checking local LSA registry settings..." -ForegroundColor Cyan

if (Test-Path $LsaPath) {
    $Value = Get-ItemProperty -Path $LsaPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Value) {
        if ($Value.DisableRestrictedAdmin -eq 0) {
            Write-Host "[+] RDP Restricted Admin Mode: Enabled (Value = 0)." -ForegroundColor Green
        } else {
            Write-Host "[-] RDP Restricted Admin Mode: Disabled (Value = $($Value.DisableRestrictedAdmin))." -ForegroundColor Red
        }
    } else {
        Write-Host "[+] RDP Restricted Admin Mode: Enabled (Default state: No registry restriction)." -ForegroundColor Green
    }
}

Write-Host "Checking RDP Session Security registry settings..." -ForegroundColor Cyan
$RdpPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"

$ExpectedRdpSettings = @{
    "DisablePasswordSaving" = 1
    "fSingleSessionPerUser" = 1
    "fDisableCdm"           = 1
    "fDisableCcm"           = 1
    "fDisableLpt"           = 1
    "fDisablePNPRedir"      = 1
    "fPromptForPassword"    = 1
    "fEncryptRPCTraffic"    = 1
    "MinEncryptionLevel"    = 3
    "MaxIdleTime"           = 900000
    "MaxDisconnectionTime"  = 60000
}

if (Test-Path $RdpPolicyPath) {
    $PolicyValues = Get-ItemProperty -Path $RdpPolicyPath -ErrorAction SilentlyContinue
    foreach ($Setting in $ExpectedRdpSettings.Keys) {
        $Val = $PolicyValues.$Setting
        $Expected = $ExpectedRdpSettings[$Setting]
        $Color = if ($Val -eq $Expected) { "Green" } else { "Red" }
        Write-Host "    - $($Setting): $Val (Expected: $Expected)" -ForegroundColor $Color
    }
} else {
    Write-Host "[-] RDP Session Policies path not found." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To establish a remote connection with Restricted Admin manually from the command line:</xhtml:em>
          <xhtml:code />
          <xhtml:code>cmd mstsc.exe /RestrictedAdmin </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-RdpRestrictedAdmin.ps1
# Description: Enables RDP Restricted Admin mode support and hardens RDP session options.

Write-Host "Applying hardening requirement: Enforce RDP Restricted Admin Mode and Session Controls..." -ForegroundColor Cyan

# 1. Enable Restricted Admin support
$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DisableRestrictedAdmin"
$ValueData = 0

if (Test-Path $LsaPath) {
    Set-ItemProperty -Path $LsaPath -Name $ValueName -Value $ValueData -Type DWord -ErrorAction Stop
    Write-Host "[+] Local system configured to accept RDP Restricted Admin connections." -ForegroundColor Green
} else {
    Write-Warning "LSA Registry path not found."
}

# 2. Harden RDP Session options in registry
$RdpPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $RdpPolicyPath)) {
    New-Item -Path $RdpPolicyPath -Force | Out-Null
}

$RdpSettings = @{
    "DisablePasswordSaving" = 1
    "fSingleSessionPerUser" = 1
    "fDisableCdm"           = 1
    "fDisableCcm"           = 1
    "fDisableLpt"           = 1
    "fDisablePNPRedir"      = 1
    "fPromptForPassword"    = 1
    "fEncryptRPCTraffic"    = 1
    "MinEncryptionLevel"    = 3
    "MaxIdleTime"           = 900000
    "MaxDisconnectionTime"  = 60000
}

foreach ($Setting in $RdpSettings.Keys) {
    Set-ItemProperty -Path $RdpPolicyPath -Name $Setting -Value $RdpSettings[$Setting] -Type DWord -ErrorAction Stop
}
Write-Host "[+] RDP session security controls applied to registry." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2019" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-021" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-021] Configure AppLocker Policies on Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-applocker-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers are Tier 0 administrative assets and must never be used for general-purpose tasks like web browsing, document viewing, or running unapproved utilities. Attackers who compromise a Domain Controller or obtain administrative access often attempt to execute custom binaries, remote access tools (RATs), or script-based tools to pivot, establish persistence, or extract the Active Directory database (NTDS.dit).</xhtml:p>
        <xhtml:p>Enforcing AppLocker policies on Domain Controllers provides the following defense-in-depth security benefits: 1. <xhtml:strong>Restricts Execution to Authorized Software</xhtml:strong>: Prevents execution of unapproved software, preventing standard user directories (such as <xhtml:code>C:\Users\</xhtml:code> or <xhtml:code>C:\Windows\Temp\</xhtml:code>) from being used to launch malicious binaries or scripts. 2. <xhtml:strong>Blocks Browser Execution</xhtml:strong>: Prevents administrative users from launching web browsers (Chrome, Edge, Firefox, Internet Explorer) directly on Domain Controllers, shutting down web-based drive-by downloads and browser-based credential leakage. 3. <xhtml:strong>Restricts Windows Installer and Script Execution</xhtml:strong>: Prevents unauthorized <xhtml:code>.msi</xhtml:code> installations and unauthorized PowerShell or VBScript scripts from running, reducing the likelihood of successful exploitation via living-off-the-land techniques. 4. <xhtml:strong>Defends Against AppLocker Bypasses</xhtml:strong>: Abusing trusted, signed Microsoft binaries (such as <xhtml:code>msbuild.exe</xhtml:code>, <xhtml:code>installutil.exe</xhtml:code>, <xhtml:code>regasm.exe</xhtml:code>, <xhtml:code>regsvcs.exe</xhtml:code>, <xhtml:code>mshta.exe</xhtml:code>, <xhtml:code>regsvr32.exe</xhtml:code>, <xhtml:code>rundll32.exe</xhtml:code>) allows attackers to execute arbitrary code bypassing default AppLocker rules. This control blocks these "Living off the Land" binaries (LOLBins) and prevents execution from user-writeable paths under <xhtml:code>%WINDIR%</xhtml:code> (such as <xhtml:code>Tasks</xhtml:code>, <xhtml:code>Temp</xhtml:code>, <xhtml:code>tracing</xhtml:code>, <xhtml:code>spool\drivers\color</xhtml:code>, etc.).</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Enable Application Identity Service</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting Domain Controllers (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Application Identity</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Define this policy setting</xhtml:strong> and configure the startup mode to <xhtml:strong>Automatic</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure AppLocker Enforcement</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Application Control Policies\AppLocker</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>AppLocker</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under the <xhtml:strong>Enforcement</xhtml:strong> tab, check <xhtml:strong>Configured</xhtml:strong> for the following rule collections:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Executable rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Audit only</xhtml:em>* for baseline testing)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Windows Installer rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Audit only</xhtml:em>*)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Script rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Audit only</xhtml:em>*)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Packaged app rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Audit only</xhtml:em>*)</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Create Default and Exception Rules</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Expand <xhtml:strong>AppLocker</xhtml:strong> and select <xhtml:strong>Executable Rules</xhtml:strong>.</xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Executable Rules</xhtml:strong> and select <xhtml:strong>Create Default Rules</xhtml:strong> (allows all files in Windows and Program Files directories, and allows local Administrators to run all files).</xhtml:li>
          <xhtml:li>Per <xhtml:strong>ANSSI R2</xhtml:strong> recommendation, do not create standalone Deny rules. Instead, configure the following path <xhtml:strong>Exceptions</xhtml:strong> on the default Allow rule for the Windows folder:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click the rule `(Default Rule) All files located in the Windows folder` and select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> On the </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for writeable directories under <xhtml:code>%WINDIR%</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Tasks\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Temp\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\tracing\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\spool\drivers\color\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> On the same </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for the following bypass binaries (LOLBins):</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msbuild.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\installutil.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mshta.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regasm.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvcs.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvr32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rundll32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\bginfo.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cdb.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cmstp.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\control.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\csi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dfsvc.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dnx.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\fsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ie4unit.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ieexec.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\infdefaultinstall.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mavinject.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdeploy.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdt.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msxsl.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\odbcconf.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\presentationhost.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rcsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\runscripthelper.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\te.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\tracker.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\xwizard.exe`</xhtml:li>
          <xhtml:li>Repeat the process for <xhtml:strong>Script Rules</xhtml:strong> by creating default rules and adding exceptions to the <xhtml:code>%WINDIR%\*</xhtml:code> Allow rule for script execution from user-writeable paths (such as <xhtml:code>%WINDIR%\Temp\*</xhtml:code> and <xhtml:code>%WINDIR%\Tasks\*</xhtml:code>).</xhtml:li>
          <xhtml:li>Disable NTVDM (16-bit application support) to prevent AppLocker bypasses via 16-bit binaries:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\16-bit Application Compatibility</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Configure </xhtml:em>
            <xhtml:em>Prevent access to 16-bit applications</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure the Application Identity service and import a robust local AppLocker policy.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-AppLockerDCPolicy.ps1">Download Script: Set-AppLockerDCPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-AppLockerDCPolicy.ps1
# Description: Configures the Application Identity service and imports a robust local AppLocker XML policy.

Write-Host "Applying hardening requirement: Configure AppLocker on Domain Controllers..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$Service = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($Service) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    if ($Service.Status -ne "Running") {
        Start-Service -Name AppIDSvc
    }
    Write-Host "[+] Application Identity service configured to start automatically and is running." -ForegroundColor Green
} else {
    Write-Error "Application Identity service (AppIDSvc) is not present on this system."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerDCPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the Application Identity service and AppLocker registry configuration:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AppLockerDCStatus.ps1">Download Script: Get-AppLockerDCStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AppLockerDCStatus.ps1
# Description: Checks the configuration state of the AppIDSvc service and AppLocker registry paths.

Write-Host "--- Auditing AppLocker Configuration ---" -ForegroundColor Cyan

# 1. Audit service state
$AppIDSvc = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($AppIDSvc) {
    $SvcColor = if ($AppIDSvc.Status -eq "Running" -and $AppIDSvc.StartType -eq "Automatic") { "Green" } else { "Yellow" }
    Write-Host "    - Application Identity Service: $($AppIDSvc.Status) | Startup: $($AppIDSvc.StartType) (Expected: Running | Automatic)" -ForegroundColor $SvcColor
} else {
    Write-Host "    - Application Identity Service: NOT INSTALLED" -ForegroundColor Red
}

# 2. Audit enforcement registry settings
$SrpPath = "HKLM:\Software\Policies\Microsoft\Windows\SrpV2"
$Collections = @("Exe", "Msi", "Script", "Appx")

if (Test-Path $SrpPath) {
    foreach ($Col in $Collections) {
        $ColPath = "$SrpPath\$Col"
        if (Test-Path $ColPath) {
            $Val = Get-ItemProperty -Path $ColPath -Name "EnforcementMode" -ErrorAction SilentlyContinue
            if ($null -ne $Val) {
                $Mode = if ($Val.EnforcementMode -eq 1) { "Enforced" } else { "Audit Only" }
                $Color = if ($Val.EnforcementMode -eq 1) { "Green" } else { "Yellow" }
                Write-Host "    - Collection $Col Enforcement: $Mode (Value: $($Val.EnforcementMode))" -ForegroundColor $Color
            } else {
                Write-Host "    - Collection $Col Enforcement: NOT CONFIGURED" -ForegroundColor Red
            }
        } else {
            Write-Host "    - Collection $Col Path: NOT FOUND" -ForegroundColor Red
        }
    }
} else {
    Write-Host "[-] AppLocker registry base path (SrpV2) not found. Policy is not deployed." -ForegroundColor Red
}

# 3. Audit NTVDM Disable Status
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (Test-Path $NtvdmPath) {
    $AppCompatVal = Get-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -ErrorAction SilentlyContinue
    if ($null -ne $AppCompatVal -and $AppCompatVal.Prevent16BitApp -eq 1) {
        Write-Host "    - NTVDM (16-bit AppCompat): Disabled (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - NTVDM (16-bit AppCompat): Enabled or Not Configured (Expected: Disabled)" -ForegroundColor Yellow
    }
} else {
    Write-Host "    - NTVDM (16-bit AppCompat): Not Configured (Expected: Disabled)" -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-AppLockerDCPolicy.ps1
# Description: Configures the Application Identity service and imports a robust local AppLocker XML policy.

Write-Host "Applying hardening requirement: Configure AppLocker on Domain Controllers..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$Service = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($Service) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    if ($Service.Status -ne "Running") {
        Start-Service -Name AppIDSvc
    }
    Write-Host "[+] Application Identity service configured to start automatically and is running." -ForegroundColor Green
} else {
    Write-Error "Application Identity service (AppIDSvc) is not present on this system."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerDCPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2021" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-022" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-022] Enable WDAC Driver Blocklist</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enable-wdac-driver-blocklist.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Attackers frequently employ "Bring Your Own Vulnerable Driver" (BYOVD) attacks to bypass Windows kernel protections. In a BYOVD attack, an adversary with administrative privileges installs a legitimate, cryptographically signed third-party driver that contains a known, exploitable vulnerability. The attacker then exploits this vulnerability to execute arbitrary code with kernel privileges, allowing them to disable security agents, dump LSASS memory, or tamper with system integrity.</xhtml:p>
        <xhtml:p>Enforcing the <xhtml:strong>Microsoft Vulnerable Driver Blocklist</xhtml:strong> via Windows Defender Application Control (WDAC) prevents known vulnerable or malicious drivers from loading in kernel space. By restricting the WDAC policy to <xhtml:strong>Kernel Mode Code Integrity (KMCI) only</xhtml:strong> (omitting user-mode enforcement), the control shields the system kernel from driver-based exploits without introducing administrative overhead or blocking standard user-mode server applications and utilities.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce the driver blocklist across all Domain Controllers, you can deploy the Microsoft recommended block rules as a custom WDAC policy.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Download the Microsoft recommended driver block rules XML from the official Microsoft documentation.</xhtml:li>
          <xhtml:li>Edit the XML to ensure it operates in <xhtml:strong>Audit Mode</xhtml:strong> first, then convert the XML configuration into a binary format:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`powershell</xhtml:li>
          <xhtml:li>ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\DriverBlocklist.xml" -BinaryFilePath "C:\WDAC\SIPolicy.p7b"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the compiled <xhtml:code>SIPolicy.p7b</xhtml:code> file to a secure local path on all target Domain Controllers (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or a share.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the local or network path to the policy file (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>).</xhtml:li>
          <xhtml:li>To ensure the built-in system driver blocklist is active on modern builds, configure the following registry setting via Group Policy Preferences:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Path</xhtml:em>*: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\CI\Config</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>VulnerableDriverBlocklistEnable</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enable the Vulnerable Driver Blocklist registry key and ensure proper configuration.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DriverBlocklist.ps1">Download Script: Configure-DriverBlocklist.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DriverBlocklistStatus.ps1">Download Script: Get-DriverBlocklistStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DriverBlocklistStatus.ps1
# Description: Audits the configuration of the Microsoft Vulnerable Driver Blocklist and HVCI state.

Write-Host "--- Auditing Vulnerable Driver Blocklist ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Check registry value
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (Test-Path $RegPath) {
    $RegValue = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $RegValue -and $RegValue.$ValueName -eq 1) {
        Write-Host "[+] Vulnerable Driver Blocklist is enabled in the registry." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Vulnerable Driver Blocklist is disabled or not set in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Code Integrity Config registry key does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Check HVCI Status
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: The Vulnerable Driver Blocklist is not fully secured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: The Vulnerable Driver Blocklist and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2022" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-024" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-024] Configure dSHeuristics Attribute</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-dsheuristics.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The <xhtml:code>dSHeuristics</xhtml:code> attribute is a Unicode string that defines forest-wide heuristic configuration settings for Active Directory. Individual characters at specific indices (1-based) modify security and protocol behaviors on Domain Controllers:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>fLDAPBlockAnonOps</xhtml:strong> (7th character): Controls anonymous LDAP operations. If set to <xhtml:code>2</xhtml:code>, anonymous binds and searches are permitted, allowing unauthorized users to map out directory structures. Setting it to <xhtml:code>0</xhtml:code> blocks anonymous operations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>fAllowAnonNSPI</xhtml:strong> (8th character): Controls anonymous access to the Name Service Provider Interface (NSPI). If set to <xhtml:code>1</xhtml:code> or any value other than <xhtml:code>0</xhtml:code>, anonymous clients can query address books, which allows user enumeration. Setting it to <xhtml:code>0</xhtml:code> restricts NSPI queries to authenticated users.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>dwAdminSDExMask</xhtml:strong> (16th character): Excludes administrative groups from the automatic security descriptor protection mechanism (the <xhtml:code>AdminSDHolder</xhtml:code> background task). By default (<xhtml:code>0</xhtml:code>), groups like Account Operators, Server Operators, Print Operators, and Backup Operators are protected. If set to non-zero, this protection is bypassed, risking privilege escalation.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>DoNotVerifyUPNAndOrSPNUniqueness</xhtml:strong> (21st character): Controls uniqueness enforcement for User Principal Names (UPN) and Service Principal Names (SPN). Disabling this check (<xhtml:code>1</xhtml:code> or non-zero) can lead to identity spoofing or credential hijacking by registering duplicate names (KB5008382).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>AttributeAuthorizationOnLDAPAdd</xhtml:strong> (28th character) and <xhtml:strong>BlockOwnerImplicitRights</xhtml:strong> (29th character): Introduced in KB5008383. Setting these to <xhtml:code>1</xhtml:code> enforces strict authorization validations and auditing during LDAP Add operations, preventing malicious creators from abusing implicit owner privileges.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>DisableConfidentialAttributeEncryptionRequirements</xhtml:strong> (31st character): Controls connection security requirements for retrieving or writing confidential attributes. Allowing unencrypted connections (non-zero) risks exposing sensitive information such as password hashes or BitLocker recovery keys on the network.</xhtml:li>
        </xhtml:ol>
        <xhtml:p>To reach the maximum Level 5 security state, all dangerous features must be disabled, and KB5008383 protections must be explicitly set to <xhtml:code>1</xhtml:code>.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Graphical Tools (ADSI Edit / Ldp.exe)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>ADSI Edit</xhtml:strong> (<xhtml:code>adsiedit.msc</xhtml:code>) with Enterprise Administrator or Domain Administrator (of the forest root) privileges.</xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>ADSI Edit</xhtml:strong> in the left pane and select <xhtml:strong>Connect to...</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Connection Point</xhtml:strong>, choose <xhtml:strong>Select a well-known Naming Context</xhtml:strong> and select <xhtml:strong>Configuration</xhtml:strong>. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the left pane, expand the tree:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Configuration -&gt; CN=Configuration,DC=... -&gt; CN=Services -&gt; CN=Windows NT -&gt; CN=Directory Service</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:code>CN=Directory Service</xhtml:code> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Locate the <xhtml:code>dSHeuristics</xhtml:code> attribute in the Attribute Editor list and click <xhtml:strong>Edit</xhtml:strong>.</xhtml:li>
          <xhtml:li>If the current value is <xhtml:code>&lt;not set&gt;</xhtml:code>, set it to the standard Level 5 string:</xhtml:li>
          <xhtml:li>
            <xhtml:code>0000000001000000000200000001130</xhtml:code>
          </xhtml:li>
          <xhtml:li>If a value is already present, modify it carefully by preserving existing non-security related positions, updating only the specific security positions:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>7th character</xhtml:em>* (fLDAPBlockAnonOps): Must not be <xhtml:code>2</xhtml:code> (change to <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>8th character</xhtml:em>* (fAllowAnonNSPI): Must be <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>16th character</xhtml:em>* (dwAdminSDExMask): Must be <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>21st character</xhtml:em>* (DoNotVerifyUPNAndOrSPNUniqueness): Must be <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>28th character</xhtml:em>* (AttributeAuthorizationOnLDAPAdd): Must be <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>29th character</xhtml:em>* (BlockOwnerImplicitRights): Must be <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>31st character</xhtml:em>* (DisableConfidentialAttributeEncryptionRequirements): Must be <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure control characters </xhtml:em>
            <xhtml:em>10th</xhtml:em>
            <xhtml:em> is `1`, </xhtml:em>
            <xhtml:em>20th</xhtml:em>
            <xhtml:em> is `2`, and </xhtml:em>
            <xhtml:em>30th</xhtml:em>* is <xhtml:code>3</xhtml:code> if the string length reaches those values.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> and apply the changes.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting programmatically.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-dSHeuristics.ps1">Download Script: Configure-dSHeuristics.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-dSHeuristics.ps1
# Description: Configures the dSHeuristics attribute to reach Level 5 security.

Write-Host "Applying hardening requirement: Configure dSHeuristics..." -ForegroundColor Cyan

# Ensure we can read the Configuration naming context
$rootDSE = [ADSI]"LDAP://RootDSE"
$configNamingContext = $rootDSE.configurationNamingContext[0]
$dsPath = "LDAP://CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNamingContext"

$dsObject = [ADSI]$dsPath
$currentHeuristics = $dsObject.Properties["dSHeuristics"].Value

$newHeuristics = ""

if ($null -eq $currentHeuristics -or $currentHeuristics -eq "") {
    # Initialize with default 31-character Level 5 string if not already configured
    $newHeuristics = "0000000001000000000200000001130"
} else {
    # If already set, we need to modify specific indices while preserving other values
    $charArray = $currentHeuristics.ToCharArray()
    
    # Pad array to at least 31 characters to support all configurations
    if ($charArray.Length -lt 31) {
        $tempArray = [char[]](New-Object char[] 31)
        for ($i = 0; $i -lt 31; $i++) {
            if ($i -lt $charArray.Length) {
                $tempArray[$i] = $charArray[$i]
            } else {
                $tempArray[$i] = [char]"0"
            }
        }
        $charArray = $tempArray
    }
    
    # 7: fLDAPBlockAnonOps (Index 6)
    if ($charArray[6] -eq [char]"2") {
        $charArray[6] = [char]"0"
    }
    
    # 8: fAllowAnonNSPI (Index 7) -&gt; must be "0"
    $charArray[7] = [char]"0"
    
    # 10: tenthChar (Index 9) -&gt; control character, must be "1"
    $charArray[9] = [char]"1"
    
    # 16: dwAdminSDExMask (Index 15) -&gt; must be "0"
    $charArray[15] = [char]"0"
    
    # 20: twentiethChar (Index 19) -&gt; control character, must be "2"
    $charArray[19] = [char]"2"
    
    # 21: DoNotVerifyUPNAndOrSPNUniqueness (Index 20) -&gt; must be "0"
    $charArray[20] = [char]"0"
    
    # 28: AttributeAuthorizationOnLDAPAdd (Index 27) -&gt; must be "1" for Level 5
    $charArray[27] = [char]"1"
    
    # 29: BlockOwnerImplicitRights (Index 28) -&gt; must be "1" for Level 5
    $charArray[28] = [char]"1"
    
    # 30: thirtiethChar (Index 29) -&gt; control character, must be "3"
    $charArray[29] = [char]"3"
    
    # 31: DisableConfidentialAttributeEncryptionRequirements (Index 30) -&gt; must be "0"
    $charArray[30] = [char]"0"
    
    $newHeuristics = [string]::new($charArray)
}

if ($currentHeuristics -ne $newHeuristics) {
    Write-Host "Updating dSHeuristics from '$currentHeuristics' to '$newHeuristics'..." -ForegroundColor Yellow
    $dsObject.Properties["dSHeuristics"].Value = $newHeuristics
    $dsObject.CommitChanges()
    Write-Host "dSHeuristics updated successfully." -ForegroundColor Green
} else {
    Write-Host "dSHeuristics is already configured securely ('$currentHeuristics'). No action required." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-dSHeuristicsStatus.ps1">Download Script: Get-dSHeuristicsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-dSHeuristicsStatus.ps1
# Description: Audits the dSHeuristics attribute settings for security compliance.

Write-Host "--- Auditing dSHeuristics Configuration ---" -ForegroundColor Cyan

$rootDSE = [ADSI]"LDAP://RootDSE"
$configNamingContext = $rootDSE.configurationNamingContext[0]
$dsPath = "LDAP://CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNamingContext"

$dsObject = [ADSI]$dsPath
$dsHeuristics = $dsObject.Properties["dSHeuristics"].Value

function Get-HeuristicChar {
    param(
        [string]$String,
        [int]$Index, # 0-based index
        [char]$Default = [char]"0"
    )
    if ($null -ne $String -and $String.Length -gt $Index) {
        return $String.Substring($Index, 1)
    }
    return $Default
}

$vulnerable = $false
$nonLevel5 = $false

if ($null -eq $dsHeuristics -or $dsHeuristics -eq "") {
    Write-Host "[!] dSHeuristics is not set. Default settings apply." -ForegroundColor Yellow
    Write-Host "    - AttributeAuthorizationOnLDAPAdd: Not Set (defaults to 0, which is Level 3/4 but NOT Level 5)" -ForegroundColor Yellow
    Write-Host "    - BlockOwnerImplicitRights: Not Set (defaults to 0, which is Level 3/4 but NOT Level 5)" -ForegroundColor Yellow
    $nonLevel5 = $true
} else {
    Write-Host "[+] Current dSHeuristics string: $dsHeuristics" -ForegroundColor Green
    
    # 7. fLDAPBlockAnonOps (Index 6)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 6
    if ($val -eq "2") {
        Write-Host "[!] VULNERABLE: fLDAPBlockAnonOps is set to '2' (Allows anonymous LDAP operations)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] fLDAPBlockAnonOps (Index 6): Set to '$val' (Anonymous LDAP operations blocked)." -ForegroundColor Green
    }
    
    # 8. fAllowAnonNSPI (Index 7)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 7
    if ($val -ne "0") {
        Write-Host "[!] VULNERABLE: fAllowAnonNSPI is set to '$val' (Allows anonymous NSPI access; must be 0)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] fAllowAnonNSPI (Index 7): Set to '0' (Anonymous NSPI blocked)." -ForegroundColor Green
    }
    
    # 16. dwAdminSDExMask (Index 15)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 15
    if ($val -ne "0") {
        Write-Host "[!] VULNERABLE: dwAdminSDExMask is set to '$val' (Disables protection for administrative groups; must be 0)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] dwAdminSDExMask (Index 15): Set to '0' (All default admin groups protected)." -ForegroundColor Green
    }
    
    # 21. DoNotVerifyUPNAndOrSPNUniqueness (Index 20)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 20
    if ($val -ne "0") {
        Write-Host "[!] VULNERABLE: DoNotVerifyUPNAndOrSPNUniqueness is set to '$val' (Bypasses UPN/SPN uniqueness checks; must be 0)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] DoNotVerifyUPNAndOrSPNUniqueness (Index 20): Set to '0' (Uniqueness checks active)." -ForegroundColor Green
    }
    
    # 28. AttributeAuthorizationOnLDAPAdd (Index 27)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 27
    if ($val -eq "2") {
        Write-Host "[!] VULNERABLE: AttributeAuthorizationOnLDAPAdd is set to '2' (Bypasses LDAP Add authorization checks)." -ForegroundColor Red
        $vulnerable = $true
    } elseif ($val -ne "1") {
        Write-Host "[!] WARNING: AttributeAuthorizationOnLDAPAdd is set to '$val' (Must be set to '1' for Level 5 security)." -ForegroundColor Yellow
        $nonLevel5 = $true
    } else {
        Write-Host "[+] AttributeAuthorizationOnLDAPAdd (Index 27): Set to '1' (Level 5 secure)." -ForegroundColor Green
    }
    
    # 29. BlockOwnerImplicitRights (Index 28)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 28
    if ($val -eq "2") {
        Write-Host "[!] VULNERABLE: BlockOwnerImplicitRights is set to '2' (Bypasses owner implicit rights protection)." -ForegroundColor Red
        $vulnerable = $true
    } elseif ($val -ne "1") {
        Write-Host "[!] WARNING: BlockOwnerImplicitRights is set to '$val' (Must be set to '1' for Level 5 security)." -ForegroundColor Yellow
        $nonLevel5 = $true
    } else {
        Write-Host "[+] BlockOwnerImplicitRights (Index 28): Set to '1' (Level 5 secure)." -ForegroundColor Green
    }
    
    # 31. DisableConfidentialAttributeEncryptionRequirements (Index 30)
    $val = Get-HeuristicChar -String $dsHeuristics -Index 30
    if ($val -ne "0") {
        Write-Host "[!] VULNERABLE: DisableConfidentialAttributeEncryptionRequirements is set to '$val' (Allows unencrypted transmission of confidential attributes; must be 0)." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] DisableConfidentialAttributeEncryptionRequirements (Index 30): Set to '0' (Requires encrypted connection)." -ForegroundColor Green
    }
}

if ($vulnerable) {
    Write-Host "[!] Result: VULNERABLE (Dangerous settings detected in dSHeuristics)." -ForegroundColor Red
} elseif ($nonLevel5) {
    Write-Host "[!] Result: Partially Secure (No highly dangerous settings, but Level 5 maximum security is not reached)." -ForegroundColor Yellow
} else {
    Write-Host "[+] Result: SECURE (Level 5 security reached)." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-dSHeuristics.ps1
# Description: Configures the dSHeuristics attribute to reach Level 5 security.

Write-Host "Applying hardening requirement: Configure dSHeuristics..." -ForegroundColor Cyan

# Ensure we can read the Configuration naming context
$rootDSE = [ADSI]"LDAP://RootDSE"
$configNamingContext = $rootDSE.configurationNamingContext[0]
$dsPath = "LDAP://CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNamingContext"

$dsObject = [ADSI]$dsPath
$currentHeuristics = $dsObject.Properties["dSHeuristics"].Value

$newHeuristics = ""

if ($null -eq $currentHeuristics -or $currentHeuristics -eq "") {
    # Initialize with default 31-character Level 5 string if not already configured
    $newHeuristics = "0000000001000000000200000001130"
} else {
    # If already set, we need to modify specific indices while preserving other values
    $charArray = $currentHeuristics.ToCharArray()
    
    # Pad array to at least 31 characters to support all configurations
    if ($charArray.Length -lt 31) {
        $tempArray = [char[]](New-Object char[] 31)
        for ($i = 0; $i -lt 31; $i++) {
            if ($i -lt $charArray.Length) {
                $tempArray[$i] = $charArray[$i]
            } else {
                $tempArray[$i] = [char]"0"
            }
        }
        $charArray = $tempArray
    }
    
    # 7: fLDAPBlockAnonOps (Index 6)
    if ($charArray[6] -eq [char]"2") {
        $charArray[6] = [char]"0"
    }
    
    # 8: fAllowAnonNSPI (Index 7) -&gt; must be "0"
    $charArray[7] = [char]"0"
    
    # 10: tenthChar (Index 9) -&gt; control character, must be "1"
    $charArray[9] = [char]"1"
    
    # 16: dwAdminSDExMask (Index 15) -&gt; must be "0"
    $charArray[15] = [char]"0"
    
    # 20: twentiethChar (Index 19) -&gt; control character, must be "2"
    $charArray[19] = [char]"2"
    
    # 21: DoNotVerifyUPNAndOrSPNUniqueness (Index 20) -&gt; must be "0"
    $charArray[20] = [char]"0"
    
    # 28: AttributeAuthorizationOnLDAPAdd (Index 27) -&gt; must be "1" for Level 5
    $charArray[27] = [char]"1"
    
    # 29: BlockOwnerImplicitRights (Index 28) -&gt; must be "1" for Level 5
    $charArray[28] = [char]"1"
    
    # 30: thirtiethChar (Index 29) -&gt; control character, must be "3"
    $charArray[29] = [char]"3"
    
    # 31: DisableConfidentialAttributeEncryptionRequirements (Index 30) -&gt; must be "0"
    $charArray[30] = [char]"0"
    
    $newHeuristics = [string]::new($charArray)
}

if ($currentHeuristics -ne $newHeuristics) {
    Write-Host "Updating dSHeuristics from '$currentHeuristics' to '$newHeuristics'..." -ForegroundColor Yellow
    $dsObject.Properties["dSHeuristics"].Value = $newHeuristics
    $dsObject.CommitChanges()
    Write-Host "dSHeuristics updated successfully." -ForegroundColor Green
} else {
    Write-Host "dSHeuristics is already configured securely ('$currentHeuristics'). No action required." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2024" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-025" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-025] Configure Security Options for Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-security-options.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Security Options control critical security settings such as anonymous access to Named Pipes, remote access to the registry (winreg), and domain member secure channel parameters. Restricting these options prevents credential sniffing, service enumeration, and remote unauthorized inspection of local configurations.</xhtml:p>
        <xhtml:p>Specifically, the following settings are configured to protect the Tier 0 administrative boundary: 1. <xhtml:strong>Server Operator Task Scheduling (`SubmitQueue`)</xhtml:strong>: Restricting Server Operators from scheduling tasks on Domain Controllers prevents privilege escalation and command execution pathways. 2. <xhtml:strong>Secure Channel Protection (`RequireStrongKey` / `AllowVulnerableChannel`)</xhtml:strong>: Restricting secure channels to strong session keys and blocking vulnerable connections mitigates coercion and impersonation attacks. 3. <xhtml:strong>Machine Password Change (`RefusePasswordChange` / `DisablePasswordChange` / `MaximumPasswordAge`)</xhtml:strong>: Ensuring domain members rotate machine account passwords at regular intervals prevents offline account hijacking while forcing the DC to process password changes correctly. 4. <xhtml:strong>Anonymous Named Pipe Restricting (`NullSessionPipes`)</xhtml:strong>: Setting NullSessionPipes to a minimum required list prevents anonymous callers from enumerating user SIDs or directories on Domain Controllers. 5. <xhtml:strong>Remote Registry Restrictions (`winreg` Exact Paths and Paths)</xhtml:strong>: Restricting remote WinReg operations prevents information disclosure and configuration scanning. 6. <xhtml:strong>Network Credentials Storage Restrictions (`DisableDomainCreds`)</xhtml:strong>: Blocking the local storage of credentials or passwords for network authentication prevents local security databases from caching reusable network hashes, hindering lateral movement.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management workstation.</xhtml:li>
          <xhtml:li>Edit the modular Domain Controllers GPO (e.g., <xhtml:code>SEC_DomainControllers_Hardening</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies as specified:</xhtml:li>
        </xhtml:ol>
        <xhtml:p>| Policy Setting | Setting Value | | :--- | :--- | | <xhtml:strong>Domain controller: Allow server operators to schedule tasks</xhtml:strong> | <xhtml:code>Disabled</xhtml:code> | | <xhtml:strong>Domain controller: Allow vulnerable Netlogon secure channel connections</xhtml:strong> | <xhtml:code>Not Configured</xhtml:code> | | <xhtml:strong>Domain controller: Refuse machine account password changes</xhtml:strong> | <xhtml:code>Disabled</xhtml:code> | | <xhtml:strong>Domain member: Disable machine account password changes</xhtml:strong> | <xhtml:code>Disabled</xhtml:code> | | <xhtml:strong>Domain member: Maximum machine account password age</xhtml:strong> | <xhtml:code>30</xhtml:code> | | <xhtml:strong>Domain member: Require strong (Windows 2000 or later) session key</xhtml:strong> | <xhtml:code>Enabled</xhtml:code> | | <xhtml:strong>Network access: Do not allow storage of passwords and credentials for network authentication</xhtml:strong> | <xhtml:code>Enabled</xhtml:code> | | <xhtml:strong>Network access: Named Pipes that can be accessed anonymously</xhtml:strong> | <xhtml:code>netlogon</xhtml:code>, <xhtml:code>samr</xhtml:code>, <xhtml:code>lsarpc</xhtml:code> | | <xhtml:strong>Network access: Remotely accessible registry paths</xhtml:strong> | <xhtml:code>System\CurrentControlSet\Control\ProductOptions</xhtml:code>, <xhtml:code>System\CurrentControlSet\Control\Server Applications</xhtml:code>, <xhtml:code>Software\Microsoft\Windows NT\CurrentVersion</xhtml:code> | | <xhtml:strong>Network access: Remotely accessible registry paths and sub-paths</xhtml:strong> | <xhtml:code>System\CurrentControlSet\Control\Print\Printers</xhtml:code>, <xhtml:code>System\CurrentControlSet\Services\Eventlog</xhtml:code>, <xhtml:code>Software\Microsoft\OLAP Server</xhtml:code>, <xhtml:code>Software\Microsoft\Windows NT\CurrentVersion\Print</xhtml:code>, <xhtml:code>Software\Microsoft\Windows NT\CurrentVersion\Windows</xhtml:code>, <xhtml:code>System\CurrentControlSet\Control\ContentIndex</xhtml:code>, <xhtml:code>System\CurrentControlSet\Control\Terminal Server</xhtml:code>, <xhtml:code>System\CurrentControlSet\Control\Terminal Server\UserConfig</xhtml:code>, <xhtml:code>System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration</xhtml:code>, <xhtml:code>Software\Microsoft\Windows NT\CurrentVersion\Perflib</xhtml:code>, <xhtml:code>System\CurrentControlSet\Services\SysmonLog</xhtml:code> |</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the registry configuration locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DCSecurityOptions.ps1">Download Script: Configure-DCSecurityOptions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DCSecurityOptions.ps1
# Description: Configures GPO Security Options registry keys for Domain Controllers.

Write-Host "Applying hardening requirement: Configure Security Options for Domain Controllers..." -ForegroundColor Cyan

# 1. Domain controller: Allow server operators to schedule tasks = Disabled (SubmitQueue = 0)
$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "SubmitQueue" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Allow server operators to schedule tasks set to Disabled." -ForegroundColor Green

# 1b. Network access: Do not allow storage of passwords and credentials for network authentication = Enabled (DisableDomainCreds = 1)
Set-ItemProperty -Path $LsaPath -Name "DisableDomainCreds" -Value 1 -Type DWord -Force
Write-Host "    Network access: Do not allow storage of credentials set to Enabled." -ForegroundColor Green

# 2. Domain controller: Allow vulnerable Netlogon secure channel connections = Not Configured / Explicitly Blocked
$NetlogonParamsPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path $NetlogonParamsPath)) {
    New-Item -Path $NetlogonParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $NetlogonParamsPath -Name "AllowVulnerableChannel" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Allow vulnerable Netlogon connections set to Disabled." -ForegroundColor Green

# 3. Domain controller: Refuse machine account password changes = Disabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "RefusePasswordChange" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Refuse machine account password changes set to Disabled." -ForegroundColor Green

# 4. Domain member: Disable machine account password changes = Disabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "DisablePasswordChange" -Value 0 -Type DWord -Force
Write-Host "    Domain member: Disable machine account password changes set to Disabled." -ForegroundColor Green

# 5. Domain member: Maximum machine account password age = 30
Set-ItemProperty -Path $NetlogonParamsPath -Name "MaximumPasswordAge" -Value 30 -Type DWord -Force
Write-Host "    Domain member: Maximum machine account password age set to 30." -ForegroundColor Green

# 6. Domain member: Require strong (Windows 2000 or later) session key = Enabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "RequireStrongKey" -Value 1 -Type DWord -Force
Write-Host "    Domain member: Require strong session key set to Enabled." -ForegroundColor Green

# 7. Network access: Named Pipes that can be accessed anonymously (netlogon, samr, lsarpc)
$LanmanServerParamsPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $LanmanServerParamsPath)) {
    New-Item -Path $LanmanServerParamsPath -Force | Out-Null
}
$NullSessionPipes = @("netlogon", "samr", "lsarpc")
Set-ItemProperty -Path $LanmanServerParamsPath -Name "NullSessionPipes" -Value $NullSessionPipes -Type MultiString -Force
Write-Host "    Network access: Named Pipes that can be accessed anonymously configured." -ForegroundColor Green

# 8. Network access: Remotely accessible registry paths
$WinregExactPath = "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedExactPaths"
if (-not (Test-Path $WinregExactPath)) {
    New-Item -Path $WinregExactPath -Force | Out-Null
}
$AllowedExactPaths = @(
    "System\CurrentControlSet\Control\ProductOptions",
    "System\CurrentControlSet\Control\Server Applications",
    "Software\Microsoft\Windows NT\CurrentVersion"
)
Set-ItemProperty -Path $WinregExactPath -Name "Machine" -Value $AllowedExactPaths -Type MultiString -Force
Write-Host "    Network access: Remotely accessible registry paths configured." -ForegroundColor Green

# 9. Network access: Remotely accessible registry paths and sub-paths
$WinregPath = "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedPaths"
if (-not (Test-Path $WinregPath)) {
    New-Item -Path $WinregPath -Force | Out-Null
}
$AllowedPaths = @(
    "System\CurrentControlSet\Control\Print\Printers",
    "System\CurrentControlSet\Services\Eventlog",
    "Software\Microsoft\OLAP Server",
    "Software\Microsoft\Windows NT\CurrentVersion\Print",
    "Software\Microsoft\Windows NT\CurrentVersion\Windows",
    "System\CurrentControlSet\Control\ContentIndex",
    "System\CurrentControlSet\Control\Terminal Server",
    "System\CurrentControlSet\Control\Terminal Server\UserConfig",
    "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration",
    "Software\Microsoft\Windows NT\CurrentVersion\Perflib",
    "System\CurrentControlSet\Services\SysmonLog"
)

# Optional AD CS or WINS sub-paths
$CertSvc = Get-Service -Name "CertSvc" -ErrorAction SilentlyContinue
if ($null -ne $CertSvc) {
    $AllowedPaths += "System\CurrentControlSet\Services\CertSvc"
    Write-Host "    AD CS detected: adding CertSvc registry path." -ForegroundColor Gray
}
$WinsSvc = Get-Service -Name "WINS" -ErrorAction SilentlyContinue
if ($null -ne $WinsSvc) {
    $AllowedPaths += "System\CurrentControlSet\Services\WINS"
    Write-Host "    WINS detected: adding WINS registry path." -ForegroundColor Gray
}

Set-ItemProperty -Path $WinregPath -Name "Machine" -Value $AllowedPaths -Type MultiString -Force
Write-Host "    Network access: Remotely accessible registry paths and sub-paths configured." -ForegroundColor Green

Write-Host "Domain Controller Security Options configuration completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>To audit local configurations, execute the following script:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DCSecurityOptionsStatus.ps1">Download Script: Get-DCSecurityOptionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DCSecurityOptionsStatus.ps1
# Description: Audits GPO Security Options registry keys for Domain Controllers.

Write-Host "--- Auditing Domain Controller Security Options ---" -ForegroundColor Cyan
$vulnerable = $false

# Helper function to check DWORD value
function Test-DwordValue {
    param(
        [string]$Path,
        [string]$ValueName,
        [int]$ExpectedValue
    )
    $Val = Get-ItemProperty -Path $Path -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -eq $Val) {
        Write-Host "    [!] VULNERABLE: $($ValueName) under $($Path) is not configured." -ForegroundColor Red
        return $true
    }
    $ActualVal = $Val.$ValueName
    if ($ActualVal -ne $ExpectedValue) {
        Write-Host "    [!] VULNERABLE: $($ValueName) is set to $($ActualVal) (Expected: $($ExpectedValue))" -ForegroundColor Red
        return $true
    }
    Write-Host "    [+] $($ValueName) is set to $($ActualVal) (Compliant)." -ForegroundColor Green
    return $false
}

# 1. Domain controller: Allow server operators to schedule tasks (SubmitQueue = 0)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -ValueName "SubmitQueue" -ExpectedValue 0) {
    $vulnerable = $true
}

# 1b. Network access: Do not allow storage of passwords and credentials for network authentication (DisableDomainCreds = 1)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -ValueName "DisableDomainCreds" -ExpectedValue 1) {
    $vulnerable = $true
}

# 2. Domain controller: Allow vulnerable Netlogon connections (AllowVulnerableChannel = 0)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters" -ValueName "AllowVulnerableChannel" -ExpectedValue 0) {
    $vulnerable = $true
}

# 3. Domain controller: Refuse machine account password changes (RefusePasswordChange = 0)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters" -ValueName "RefusePasswordChange" -ExpectedValue 0) {
    $vulnerable = $true
}

# 4. Domain member: Disable machine account password changes (DisablePasswordChange = 0)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters" -ValueName "DisablePasswordChange" -ExpectedValue 0) {
    $vulnerable = $true
}

# 5. Domain member: Maximum machine account password age (MaximumPasswordAge = 30)
$MaxAgeVal = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters" -Name "MaximumPasswordAge" -ErrorAction SilentlyContinue
if ($null -eq $MaxAgeVal) {
    Write-Host "    [!] VULNERABLE: MaximumPasswordAge is not configured." -ForegroundColor Red
    $vulnerable = $true
} else {
    $ActualAge = $MaxAgeVal.MaximumPasswordAge
    if ($ActualAge -gt 30 -or $ActualAge -eq 0) {
        Write-Host "    [!] VULNERABLE: MaximumPasswordAge is $($ActualAge) (Expected: 30 or fewer, but not 0)" -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "    [+] MaximumPasswordAge is $($ActualAge) (Compliant)." -ForegroundColor Green
    }
}

# 6. Domain member: Require strong session key (RequireStrongKey = 1)
if (Test-DwordValue -Path "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters" -ValueName "RequireStrongKey" -ExpectedValue 1) {
    $vulnerable = $true
}

# Helper function to check MultiString value
function Test-MultiStringValue {
    param(
        [string]$Path,
        [string]$ValueName,
        [string[]]$ExpectedElements
    )
    $Val = Get-ItemProperty -Path $Path -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -eq $Val) {
        Write-Host "    [!] VULNERABLE: $($ValueName) under $($Path) is not configured." -ForegroundColor Red
        return $true
    }
    $ActualList = $Val.$ValueName
    $Missing = @()
    foreach ($E in $ExpectedElements) {
        $Found = $false
        foreach ($A in $ActualList) {
            if ($A.Trim().ToLower() -eq $E.ToLower()) {
                $Found = $true
                break
            }
        }
        if (-not $Found) {
            $Missing += $E
        }
    }
    if ($Missing.Count -gt 0) {
        Write-Host "    [!] VULNERABLE: $($ValueName) is missing elements: $($Missing -join ', ')" -ForegroundColor Red
        return $true
    }
    Write-Host "    [+] $($ValueName) contains all required elements (Compliant)." -ForegroundColor Green
    return $false
}

# 7. Network access: Named Pipes that can be accessed anonymously
$RequiredPipes = @("netlogon", "samr", "lsarpc")
if (Test-MultiStringValue -Path "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters" -ValueName "NullSessionPipes" -ExpectedElements $RequiredPipes) {
    $vulnerable = $true
}

# 8. Network access: Remotely accessible registry paths
$RequiredExactPaths = @(
    "System\CurrentControlSet\Control\ProductOptions",
    "System\CurrentControlSet\Control\Server Applications",
    "Software\Microsoft\Windows NT\CurrentVersion"
)
if (Test-MultiStringValue -Path "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedExactPaths" -ValueName "Machine" -ExpectedElements $RequiredExactPaths) {
    $vulnerable = $true
}

# 9. Network access: Remotely accessible registry paths and sub-paths
$RequiredPaths = @(
    "System\CurrentControlSet\Control\Print\Printers",
    "System\CurrentControlSet\Services\Eventlog",
    "Software\Microsoft\OLAP Server",
    "Software\Microsoft\Windows NT\CurrentVersion\Print",
    "Software\Microsoft\Windows NT\CurrentVersion\Windows",
    "System\CurrentControlSet\Control\ContentIndex",
    "System\CurrentControlSet\Control\Terminal Server",
    "System\CurrentControlSet\Control\Terminal Server\UserConfig",
    "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration",
    "Software\Microsoft\Windows NT\CurrentVersion\Perflib",
    "System\CurrentControlSet\Services\SysmonLog"
)

# Optional AD CS or WINS sub-paths
$CertSvc = Get-Service -Name "CertSvc" -ErrorAction SilentlyContinue
if ($null -ne $CertSvc) {
    $RequiredPaths += "System\CurrentControlSet\Services\CertSvc"
}
$WinsSvc = Get-Service -Name "WINS" -ErrorAction SilentlyContinue
if ($null -ne $WinsSvc) {
    $RequiredPaths += "System\CurrentControlSet\Services\WINS"
}

if (Test-MultiStringValue -Path "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedPaths" -ValueName "Machine" -ExpectedElements $RequiredPaths) {
    $vulnerable = $true
}

if ($vulnerable) {
    Write-Host "Audit result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DCSecurityOptions.ps1
# Description: Configures GPO Security Options registry keys for Domain Controllers.

Write-Host "Applying hardening requirement: Configure Security Options for Domain Controllers..." -ForegroundColor Cyan

# 1. Domain controller: Allow server operators to schedule tasks = Disabled (SubmitQueue = 0)
$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "SubmitQueue" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Allow server operators to schedule tasks set to Disabled." -ForegroundColor Green

# 1b. Network access: Do not allow storage of passwords and credentials for network authentication = Enabled (DisableDomainCreds = 1)
Set-ItemProperty -Path $LsaPath -Name "DisableDomainCreds" -Value 1 -Type DWord -Force
Write-Host "    Network access: Do not allow storage of credentials set to Enabled." -ForegroundColor Green

# 2. Domain controller: Allow vulnerable Netlogon secure channel connections = Not Configured / Explicitly Blocked
$NetlogonParamsPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path $NetlogonParamsPath)) {
    New-Item -Path $NetlogonParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $NetlogonParamsPath -Name "AllowVulnerableChannel" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Allow vulnerable Netlogon connections set to Disabled." -ForegroundColor Green

# 3. Domain controller: Refuse machine account password changes = Disabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "RefusePasswordChange" -Value 0 -Type DWord -Force
Write-Host "    Domain controller: Refuse machine account password changes set to Disabled." -ForegroundColor Green

# 4. Domain member: Disable machine account password changes = Disabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "DisablePasswordChange" -Value 0 -Type DWord -Force
Write-Host "    Domain member: Disable machine account password changes set to Disabled." -ForegroundColor Green

# 5. Domain member: Maximum machine account password age = 30
Set-ItemProperty -Path $NetlogonParamsPath -Name "MaximumPasswordAge" -Value 30 -Type DWord -Force
Write-Host "    Domain member: Maximum machine account password age set to 30." -ForegroundColor Green

# 6. Domain member: Require strong (Windows 2000 or later) session key = Enabled
Set-ItemProperty -Path $NetlogonParamsPath -Name "RequireStrongKey" -Value 1 -Type DWord -Force
Write-Host "    Domain member: Require strong session key set to Enabled." -ForegroundColor Green

# 7. Network access: Named Pipes that can be accessed anonymously (netlogon, samr, lsarpc)
$LanmanServerParamsPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path $LanmanServerParamsPath)) {
    New-Item -Path $LanmanServerParamsPath -Force | Out-Null
}
$NullSessionPipes = @("netlogon", "samr", "lsarpc")
Set-ItemProperty -Path $LanmanServerParamsPath -Name "NullSessionPipes" -Value $NullSessionPipes -Type MultiString -Force
Write-Host "    Network access: Named Pipes that can be accessed anonymously configured." -ForegroundColor Green

# 8. Network access: Remotely accessible registry paths
$WinregExactPath = "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedExactPaths"
if (-not (Test-Path $WinregExactPath)) {
    New-Item -Path $WinregExactPath -Force | Out-Null
}
$AllowedExactPaths = @(
    "System\CurrentControlSet\Control\ProductOptions",
    "System\CurrentControlSet\Control\Server Applications",
    "Software\Microsoft\Windows NT\CurrentVersion"
)
Set-ItemProperty -Path $WinregExactPath -Name "Machine" -Value $AllowedExactPaths -Type MultiString -Force
Write-Host "    Network access: Remotely accessible registry paths configured." -ForegroundColor Green

# 9. Network access: Remotely accessible registry paths and sub-paths
$WinregPath = "HKLM:\System\CurrentControlSet\Control\SecurePipeServers\winreg\AllowedPaths"
if (-not (Test-Path $WinregPath)) {
    New-Item -Path $WinregPath -Force | Out-Null
}
$AllowedPaths = @(
    "System\CurrentControlSet\Control\Print\Printers",
    "System\CurrentControlSet\Services\Eventlog",
    "Software\Microsoft\OLAP Server",
    "Software\Microsoft\Windows NT\CurrentVersion\Print",
    "Software\Microsoft\Windows NT\CurrentVersion\Windows",
    "System\CurrentControlSet\Control\ContentIndex",
    "System\CurrentControlSet\Control\Terminal Server",
    "System\CurrentControlSet\Control\Terminal Server\UserConfig",
    "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration",
    "Software\Microsoft\Windows NT\CurrentVersion\Perflib",
    "System\CurrentControlSet\Services\SysmonLog"
)

# Optional AD CS or WINS sub-paths
$CertSvc = Get-Service -Name "CertSvc" -ErrorAction SilentlyContinue
if ($null -ne $CertSvc) {
    $AllowedPaths += "System\CurrentControlSet\Services\CertSvc"
    Write-Host "    AD CS detected: adding CertSvc registry path." -ForegroundColor Gray
}
$WinsSvc = Get-Service -Name "WINS" -ErrorAction SilentlyContinue
if ($null -ne $WinsSvc) {
    $AllowedPaths += "System\CurrentControlSet\Services\WINS"
    Write-Host "    WINS detected: adding WINS registry path." -ForegroundColor Gray
}

Set-ItemProperty -Path $WinregPath -Name "Machine" -Value $AllowedPaths -Type MultiString -Force
Write-Host "    Network access: Remotely accessible registry paths and sub-paths configured." -ForegroundColor Green

Write-Host "Domain Controller Security Options configuration completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2025" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-027" severity="low" weight="10.0" selected="false">
      <title>[REQ-DC-027] Configure Telemetry, Diagnostics and Privacy Options for Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-telemetry-privacy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Restricting telemetry, remote help channels, data sharing features, and diagnostic logs on Domain Controllers limits target exposure and data leakage: 1. <xhtml:strong>Minimize Telemetry and Personalization Leakage</xhtml:strong>: Domain Controllers process highly sensitive security directory events, administrative tasks, and structural secrets. Personalization telemetry (such as handwriting sharing, speech data, and Customer Experience Improvement Programs) sends host telemetry to external cloud endpoints. 2. <xhtml:strong>Disable Non-Essential Network Services</xhtml:strong>: Features like Online Help, printing over HTTP, and Windows Spotlight create unauthenticated outbound connections to cloud platforms. 3. <xhtml:strong>Restrict Diagnostic Tools</xhtml:strong>: Interactive diagnostic channels like the Microsoft Support Diagnostic Tool (MSDT) have been targeted in remote execution exploits (e.g., Follina). Restricting interactive troubleshooting tools prevents adversaries from utilizing diagnostic capabilities for code execution. 4. <xhtml:strong>Prevent Cloud Synchronization</xhtml:strong>: Message cloud synchronization, push-to-install services, and cloud-based search highlights run background processes that expose local queries and operations to external networks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Configure Group Policy settings to disable telemetry and cloud services:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the appropriate GPO targeting the Domain Controllers (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following settings under <xhtml:strong>Computer Configuration</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> `Control Panel\Allow Online Tips` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Network\Fonts\Enable Font Providers` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Start Menu and Taskbar\Turn off notifications network usage` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>* <xhtml:code>System\Internet Communication Management\Internet Communication settings</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off handwriting personalization data sharing` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off handwriting recognition error reporting` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off printing over HTTP` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off Search Companion content file updates` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off the "Order Prints" picture task` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off the "Publish to Web" task for files and folders` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off the Windows Messenger Customer Experience Improvement Program` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off Windows Customer Experience Improvement Program` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Turn off Windows Error Reporting` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `System\Troubleshooting and Diagnostics\Microsoft Support Diagnostic Tool\Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `System\User Profiles\Turn off the advertising ID` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\App Package Deployment\Allow a Windows app to share application data between users` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Camera\Allow Use of Camera` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Data Collection and Preview Builds\Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service` -&gt; </xhtml:em>
            <xhtml:em>Enabled: Disable Authenticated Proxy usage</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Location and Sensors\Turn off location` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Messaging\Allow Message Service Cloud Sync` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Push to Install\Turn off Push To Install service` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Search\Allow Cloud Search` -&gt; </xhtml:em>
            <xhtml:em>Enabled: Disable Cloud Search</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Search\Allow search highlights` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Software Protection Platform\Turn off KMS Client Online AVS Validation` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Windows Ink Workspace\Allow suggested apps in Windows Ink Workspace` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Configure the following settings under <xhtml:strong>User Configuration</xhtml:strong> (or configure via GPO Preferences Registry if Loopback Processing is not active):</xhtml:li>
          <xhtml:li>
            <xhtml:em> `System\Internet Communication Management\Internet Communication Settings\Turn off Help Experience Improvement Program` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Cloud Content\Do not use diagnostic data for tailored experiences` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Cloud Content\Turn off all Windows spotlight features` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `Windows Components\Windows Media Player\Playback\Prevent Codec Download` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enforce telemetry and privacy registry hardening.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DCTelemetryPrivacy.ps1">Download Script: Configure-DCTelemetryPrivacy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DCTelemetryPrivacy.ps1
# Description: Configures telemetry, diagnostic, and privacy options for Domain Controllers.

Write-Host "Applying Telemetry and Privacy baseline settings..." -ForegroundColor Cyan

# Helper function to create keys and set values safely
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}

# 1. HKLM Policy Configurations
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "AllowOnlineTips" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "EnableFontProviders" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoCloudApplicationNotification" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\TabletPC" "PreventHandwritingDataSharing" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" "PreventHandwritingErrorReports" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\SearchCompanion" "DisableContentFileUpdates" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoOnlinePrintsWizard" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoPublishingWizard" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Messenger\Client" "CEIP" 2
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\SQMClient\Windows" "CEIPEnable" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" "Disabled" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" "DoReport" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" "DisableQueryRemoteServer" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" "DisabledByGroupPolicy" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" "AllowSharedLocalAppData" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Camera" "AllowCamera" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" "DisableEnterpriseAuthProxy" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" "DisableLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Messaging" "AllowMessageSync" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\PushToInstall" "DisablePushToInstall" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "AllowCloudSearch" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "EnableDynamicContentInWSB" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" "NoGenTicket" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" "AllowSuggestedAppsInWindowsInkWorkspace" 0

Write-Host "HKLM telemetry parameters configured." -ForegroundColor Green

# 2. Configure Current User Settings (HKCU)
$AssistancePath = "HKCU:\Software\Policies\Microsoft\Assistance\Client\1.0"
Set-RegDWord $AssistancePath "NoImplicitFeedback" 1

$CloudContentPath = "HKCU:\Software\Policies\Microsoft\Windows\CloudContent"
Set-RegDWord $CloudContentPath "DisableTailoredExperiencesWithDiagnosticData" 1
Set-RegDWord $CloudContentPath "DisableWindowsSpotlightFeatures" 1

$MediaPlayerPath = "HKCU:\Software\Policies\Microsoft\WindowsMediaPlayer"
Set-RegDWord $MediaPlayerPath "PreventCodecDownload" 1

Write-Host "HKCU telemetry parameters configured." -ForegroundColor Green

# 3. Configure Default User Hive Settings (HKU\DefaultUser)
$DefaultUserHive = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultUserHive) {
    Write-Host "Loading Default User hive..." -ForegroundColor Gray
    reg load HKU\DefaultUser $DefaultUserHive | Out-Null
    
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Assistance\Client\1.0" "NoImplicitFeedback" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent" "DisableTailoredExperiencesWithDiagnosticData" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent" "DisableWindowsSpotlightFeatures" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\WindowsMediaPlayer" "PreventCodecDownload" 1
    
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
    Write-Host "Default User hive configurations applied." -ForegroundColor Green
} else {
    Write-Warning "Default User hive not found."
}

Write-Host "Telemetry and privacy settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DCTelemetryPrivacyStatus.ps1">Download Script: Get-DCTelemetryPrivacyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DCTelemetryPrivacyStatus.ps1
# Description: Audits registry configuration of telemetry, diagnostic, and privacy settings on Domain Controllers.

Write-Host "--- Auditing Domain Controller Telemetry and Privacy Settings ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to audit registry properties
function Test-RegistryValue ($path, $name, $expectedValue) {
    $val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    $color = "Red"
    if ($actual -eq $expectedValue) {
        $color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - Registry Setting: $($name) | Actual: '$($actual)' (Expected: '$($expectedValue)')" -ForegroundColor $color
}

# 1. HKLM Audits
Write-Host "Auditing HKLM Settings..." -ForegroundColor Gray
Test-RegistryValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "AllowOnlineTips" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "EnableFontProviders" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoCloudApplicationNotification" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\TabletPC" "PreventHandwritingDataSharing" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" "PreventHandwritingErrorReports" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\SearchCompanion" "DisableContentFileUpdates" 1
Test-RegistryValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoOnlinePrintsWizard" 1
Test-RegistryValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoPublishingWizard" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Messenger\Client" "CEIP" 2
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\SQMClient\Windows" "CEIPEnable" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" "Disabled" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" "DoReport" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" "DisableQueryRemoteServer" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" "DisabledByGroupPolicy" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" "AllowSharedLocalAppData" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Camera" "AllowCamera" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" "DisableEnterpriseAuthProxy" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" "DisableLocation" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Messaging" "AllowMessageSync" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\PushToInstall" "DisablePushToInstall" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "AllowCloudSearch" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "EnableDynamicContentInWSB" 0
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" "NoGenTicket" 1
Test-RegistryValue "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" "AllowSuggestedAppsInWindowsInkWorkspace" 0

# 2. HKCU Audits
Write-Host "Auditing HKCU Settings..." -ForegroundColor Gray
Test-RegistryValue "HKCU:\Software\Policies\Microsoft\Assistance\Client\1.0" "NoImplicitFeedback" 1
Test-RegistryValue "HKCU:\Software\Policies\Microsoft\Windows\CloudContent" "DisableTailoredExperiencesWithDiagnosticData" 1
Test-RegistryValue "HKCU:\Software\Policies\Microsoft\Windows\CloudContent" "DisableWindowsSpotlightFeatures" 1
Test-RegistryValue "HKCU:\Software\Policies\Microsoft\WindowsMediaPlayer" "PreventCodecDownload" 1

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DCTelemetryPrivacy.ps1
# Description: Configures telemetry, diagnostic, and privacy options for Domain Controllers.

Write-Host "Applying Telemetry and Privacy baseline settings..." -ForegroundColor Cyan

# Helper function to create keys and set values safely
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}

# 1. HKLM Policy Configurations
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "AllowOnlineTips" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "EnableFontProviders" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoCloudApplicationNotification" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\TabletPC" "PreventHandwritingDataSharing" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" "PreventHandwritingErrorReports" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\SearchCompanion" "DisableContentFileUpdates" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoOnlinePrintsWizard" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoPublishingWizard" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Messenger\Client" "CEIP" 2
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\SQMClient\Windows" "CEIPEnable" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" "Disabled" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" "DoReport" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" "DisableQueryRemoteServer" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" "DisabledByGroupPolicy" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" "AllowSharedLocalAppData" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Camera" "AllowCamera" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" "DisableEnterpriseAuthProxy" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" "DisableLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Messaging" "AllowMessageSync" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\PushToInstall" "DisablePushToInstall" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "AllowCloudSearch" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" "EnableDynamicContentInWSB" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" "NoGenTicket" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" "AllowSuggestedAppsInWindowsInkWorkspace" 0

Write-Host "HKLM telemetry parameters configured." -ForegroundColor Green

# 2. Configure Current User Settings (HKCU)
$AssistancePath = "HKCU:\Software\Policies\Microsoft\Assistance\Client\1.0"
Set-RegDWord $AssistancePath "NoImplicitFeedback" 1

$CloudContentPath = "HKCU:\Software\Policies\Microsoft\Windows\CloudContent"
Set-RegDWord $CloudContentPath "DisableTailoredExperiencesWithDiagnosticData" 1
Set-RegDWord $CloudContentPath "DisableWindowsSpotlightFeatures" 1

$MediaPlayerPath = "HKCU:\Software\Policies\Microsoft\WindowsMediaPlayer"
Set-RegDWord $MediaPlayerPath "PreventCodecDownload" 1

Write-Host "HKCU telemetry parameters configured." -ForegroundColor Green

# 3. Configure Default User Hive Settings (HKU\DefaultUser)
$DefaultUserHive = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultUserHive) {
    Write-Host "Loading Default User hive..." -ForegroundColor Gray
    reg load HKU\DefaultUser $DefaultUserHive | Out-Null
    
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Assistance\Client\1.0" "NoImplicitFeedback" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent" "DisableTailoredExperiencesWithDiagnosticData" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent" "DisableWindowsSpotlightFeatures" 1
    Set-RegDWord "Registry::HKU\DefaultUser\Software\Policies\Microsoft\WindowsMediaPlayer" "PreventCodecDownload" 1
    
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
    Write-Host "Default User hive configurations applied." -ForegroundColor Green
} else {
    Write-Warning "Default User hive not found."
}

Write-Host "Telemetry and privacy settings applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2027" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-028" severity="medium" weight="10.0" selected="false">
      <title>[REQ-DC-028] Configure Untrusted Font Blocking for Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-untrusted-font-blocking.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Font files (TrueType, OpenType, and others) are highly complex formats that require advanced parsing logic. Historically, font parsing in Windows was performed by the Graphics Device Interface (GDI) within the operating system kernel. Vulnerabilities in the kernel-mode font parser (such as buffer overflows or remote code execution) have been frequently exploited by threat actors to execute arbitrary code with kernel-level privileges.</xhtml:p>
        <xhtml:p>Enabling Untrusted Font Blocking limits the attack surface of the graphics subsystem on Domain Controllers: 1. <xhtml:strong>Kernel Attack Surface Reduction</xhtml:strong>: Restricting the system to only load trusted fonts installed in the <xhtml:code>%windir%\Fonts</xhtml:code> system directory prevents the processing of malicious, web-delivered, or embedded font files. 2. <xhtml:strong>Mitigation of Document-Based Exploits</xhtml:strong>: Prevents malicious font files embedded in Microsoft Office documents, PDFs, or web pages from triggering parsing vulnerabilities in the context of administrative sessions on the Domain Controller.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Mitigation Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Untrusted Font Blocking</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Mitigation Options</xhtml:em>*: <xhtml:code>Block untrusted fonts and log events</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the Domain Controllers Organizational Unit (OU) containing the target servers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone systems or during reference image build phases.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-UntrustedFontBlocking.ps1">Download Script: Configure-UntrustedFontBlocking.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events on Domain Controllers.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-UntrustedFontBlockingStatus.ps1">Download Script: Get-UntrustedFontBlockingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-UntrustedFontBlockingStatus.ps1
# Description: Checks the current configuration state of Untrusted Font Blocking registry setting on Domain Controllers.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ExpectedValue = "1000000000000"

Write-Host "Auditing hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (Test-Path $RegPath) {
    $value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $value -and $value.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. Untrusted fonts are blocked and logged ($($ValueName) = $($ExpectedValue))." -ForegroundColor Green
        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. Untrusted fonts are not configured to block and log." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events on Domain Controllers.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2028" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-029" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-029] Configure svchost.exe Mitigation Options</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0) and Domain Member Servers (Tier 1). <xhtml:em>(For Privileged Access Workstations, refer to [REQ-PAW-017](../07-paws/configure-svchost-mitigation.md); for Tier 2 Client Workstations, refer to [REQ-END-030](../08-endpoints/configure-svchost-mitigation.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2022, Windows Server 2025, Windows Server Semi-Annual Channel (1903 and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-svchost-mitigation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Service Host (<xhtml:code>svchost.exe</xhtml:code>) process is an essential operating system component responsible for hosting multiple background services in Windows. Because <xhtml:code>svchost.exe</xhtml:code> processes execute with the highest operating system privileges (typically <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>, <xhtml:code>NT AUTHORITY\LOCAL SERVICE</xhtml:code>, or <xhtml:code>NT AUTHORITY\NETWORK SERVICE</xhtml:code>), they represent high-value targets for adversaries seeking privilege escalation, persistence, and defense evasion across both Domain Controllers and enterprise Domain Member Servers.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To ensure operational stability and permit phased deployment, configure separate GPOs for Tier 0 Domain Controllers and Tier 1 Member Servers.</xhtml:p>
        <xhtml:h4>1. Configure GPO for Domain Controllers (Tier 0)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a Domain Controller or management workstation.</xhtml:li>
          <xhtml:li>Edit the baseline Domain Controller hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Service Control Manager Settings\Security Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Enable svchost.exe mitigation options</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the <xhtml:strong>Domain Controllers</xhtml:strong> Organizational Unit (<xhtml:code>OU=Domain Controllers,DC=contoso,DC=com</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure GPO for Domain Member Servers (Tier 1)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In <xhtml:code>gpmc.msc</xhtml:code>, edit the baseline Member Server hardening GPO (e.g., <xhtml:code>GPO_Hardening_MemberServers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Service Control Manager Settings\Security Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure <xhtml:strong>Enable svchost.exe mitigation options</xhtml:strong> to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to your <xhtml:strong>Member Servers</xhtml:strong> Organizational Units (e.g., <xhtml:code>OU=Tier1_Servers,OU=Servers,DC=contoso,DC=com</xhtml:code>).</xhtml:li>
          <xhtml:li>Stage deployment across non-production and pilot server groups before enabling domain-wide.</xhtml:li>
          <xhtml:li>Perform a scheduled server restart during an authorized maintenance window to apply process mitigations across all system services.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally during base image creation, automated provisioning, or standalone server testing.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-SvchostMitigation.ps1">Download Script: Configure-SvchostMitigation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows Server 2022 / Build 20348)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows Server 2022+ or Windows 10 1903+)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options: $($_.Exception.Message)"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SvchostMitigationStatus.ps1">Download Script: Get-SvchostMitigationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SvchostMitigationStatus.ps1
# Description: Audits the configuration state of svchost.exe mitigation options.

[CmdletBinding()]
param()

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ExpectedValue = 1

Write-Host "Auditing hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "Audit Result: Non-Applicable / Unsupported. OS build $($osBuild) precedes the introduction of svchost mitigation policy (requires Windows Server 2022+ or Windows 10 1903+)."
    exit 1
}

if (Test-Path -Path $RegPath) {
    $item = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $item -and $item.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. svchost.exe mitigation policy is enabled in registry ($($RegPath)\$($ValueName) = 1)." -ForegroundColor Green

        # Optional check for running svchost processes
        $svchostProcesses = Get-Process -Name "svchost" -ErrorAction SilentlyContinue
        if ($svchostProcesses) {
            Write-Host "Found $($svchostProcesses.Count) running svchost.exe process instances. Process mitigation flags are enforced dynamically at process spawn by the Service Control Manager." -ForegroundColor Gray
        }

        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. svchost.exe mitigation options are disabled or not configured ($($RegPath)\$($ValueName))." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows Server 2022 / Build 20348)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows Server 2022+ or Windows 10 1903+)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options: $($_.Exception.Message)"
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2029" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-030" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-030] Secure Directory Services Restore Mode (DSRM) and Recovery Parameters</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, 2019, 2022, 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/harden-dsrm-recovery-mode.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Directory Services Restore Mode (DSRM) is a special boot mode for Domain Controllers that allows administrators to repair or restore the Active Directory database (NTDS.dit). DSRM uses a local Administrator account separate from the AD directory.</xhtml:p>
        <xhtml:p>If DSRM is not secured: 1. <xhtml:strong>Network Authentication Abuse</xhtml:strong>: By default, or if misconfigured (e.g. <xhtml:code>DsrmAdminLogonBehavior</xhtml:code> set to <xhtml:code>0</xhtml:code> or <xhtml:code>2</xhtml:code>), the local DSRM administrator account can authenticate over the network to the Domain Controller. Since this account has a static password (often never changed since DC promotion), it can be targeted for brute-forcing, pass-the-hash, or DCSync credential retrieval. 2. <xhtml:strong>Offline Recovery Attacks</xhtml:strong>: If the DC is booted in Safe Mode/DSRM, local controls are reduced.</xhtml:p>
        <xhtml:p>Setting <xhtml:code>DsrmAdminLogonBehavior</xhtml:code> to <xhtml:code>1</xhtml:code> ensures the DSRM Administrator account can only log on locally, and only when the DC is booted into DSRM mode. Setting it to <xhtml:code>2</xhtml:code> allows logon when the AD service is stopped, which is also a risk.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong> with the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>System\CurrentControlSet\Control\Lsa</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>DsrmAdminLogonBehavior</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>00000001</xhtml:code> (Hexadecimal)</xhtml:li>
          <xhtml:li>Deploy and link the GPO to enforce the registry setting domain-wide.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>To automate verification and local remediation of the DSRM configuration:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DsrmHardening.ps1">Download Script: Set-DsrmHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DsrmHardening.ps1
# Description: Configures DsrmAdminLogonBehavior to restrict network logons.

$RegPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DsrmAdminLogonBehavior"
$ValueData = 1 # Restrict network logons

Write-Host "Applying hardening: Restricting DSRM Admin Logon Behavior..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "[+] Registry parameter set successfully: $ValueName = $ValueData" -ForegroundColor Green

# Instructions for DSRM password sync
Write-Host "`n[NOTE] Ensure that you synchronize the DSRM Administrator password with the Domain Administrator account." -ForegroundColor Yellow
Write-Host "Run the following command to sync passwords:" -ForegroundColor Yellow
Write-Host "  ntdsutil `"set dsrm password`" `"sync from domain account administrator`" q q" -ForegroundColor Yellow</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the DSRM configuration status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DsrmHardeningStatus.ps1">Download Script: Get-DsrmHardeningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DsrmHardeningStatus.ps1
# Check if DsrmAdminLogonBehavior registry parameter is set to 1.

$RegPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DsrmAdminLogonBehavior"

if (-not (Test-Path $RegPath)) {
    Write-Host "[!] NON-COMPLIANT: Registry key '$RegPath' does not exist." -ForegroundColor Red
    exit 1
}

$Value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue

if ($null -eq $Value -or $Value.$ValueName -ne 1) {
    Write-Host "[!] NON-COMPLIANT: DSRM network logon is not restricted (DsrmAdminLogonBehavior is not 1)." -ForegroundColor Red
    exit 1
} else {
    Write-Host "[+] COMPLIANT: DSRM network logon is restricted (DsrmAdminLogonBehavior = 1)." -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DsrmHardening.ps1
# Description: Configures DsrmAdminLogonBehavior to restrict network logons.

$RegPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "DsrmAdminLogonBehavior"
$ValueData = 1 # Restrict network logons

Write-Host "Applying hardening: Restricting DSRM Admin Logon Behavior..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "[+] Registry parameter set successfully: $ValueName = $ValueData" -ForegroundColor Green

# Instructions for DSRM password sync
Write-Host "`n[NOTE] Ensure that you synchronize the DSRM Administrator password with the Domain Administrator account." -ForegroundColor Yellow
Write-Host "Run the following command to sync passwords:" -ForegroundColor Yellow
Write-Host "  ntdsutil `"set dsrm password`" `"sync from domain account administrator`" q q" -ForegroundColor Yellow</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2030" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-031" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-031] Configure NTP Time Synchronization on the PDC Emulator</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (specifically the PDC Emulator FSMO role owner)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-pdc-time-sync.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory relies heavily on Kerberos authentication, which has a default maximum clock skew limit of 5 minutes to prevent replay attacks. If the system clocks of Domain Controllers and member endpoints drift, authentication will fail, causing directory service outages.</xhtml:p>
        <xhtml:p>The Domain Controller holding the Primary Domain Controller (PDC) Emulator FSMO role acts as the root time source for the entire Active Directory forest. All other Domain Controllers synchronize their time from the PDC Emulator, and member servers and workstations synchronize their time from their local authenticating Domain Controllers (using the NT5DS domain hierarchy).</xhtml:p>
        <xhtml:p>If the PDC Emulator is not configured to synchronize with a reliable external time source or hardware clock: 1. <xhtml:strong>Clock Drift Outages</xhtml:strong>: The entire forest clock can drift over time, eventually exceeding the 5-minute skew limit for external integrations or causing authentication failures. 2. <xhtml:strong>Replay Attacks</xhtml:strong>: A lack of synchronized time compromises the security of Kerberos tokens, leaving the environment vulnerable to replay attacks.</xhtml:p>
        <xhtml:p>Configuring the PDC Emulator as a reliable NTP server synchronizing with a secure, trusted reference clock prevents time drift and secures Kerberos transactions.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To configure the PDC Emulator time synchronization via a dedicated GPO linked to the Domain Controllers OU (utilizing WMI filtering to target only the PDC Emulator):</xhtml:p>
        <xhtml:h4>1. Create a WMI Filter for the PDC Emulator Role</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>WMI Filters</xhtml:strong> in the console tree and select <xhtml:strong>New</xhtml:strong>.</xhtml:li>
          <xhtml:li>Name the filter <xhtml:code>Target PDC Emulator</xhtml:code>.</xhtml:li>
          <xhtml:li>Add the following WQL query:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`sql</xhtml:li>
          <xhtml:li>Select * from Win32_DirectoryServerInfo where DomainRole = 5</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Save</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Windows Time Service Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Create a new GPO named <xhtml:code>SEC_DomainControllers_TimeSync</xhtml:code> and link it to the <xhtml:strong>Domain Controllers</xhtml:strong> OU.</xhtml:li>
          <xhtml:li>Under the WMI Filtering section of the GPO, select the <xhtml:code>Target PDC Emulator</xhtml:code> filter.</xhtml:li>
          <xhtml:li>Edit the GPO and navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service\Time Providers</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure Windows NTP Client</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>NtpServer</xhtml:em>*: <xhtml:code>time.windows.com,0x8</xhtml:code> (or the IP/FQDN of your local hardware NTP server in air-gapped systems).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Type</xhtml:em>*: <xhtml:code>NTP</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>CrossSiteSyncFlags</xhtml:em>*: <xhtml:code>2</xhtml:code> (All).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>ResolvePeerBackoffMinutes</xhtml:em>*: <xhtml:code>15</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>ResolvePeerBackoffMaxTimes</xhtml:em>*: <xhtml:code>7</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>SpecialPollInterval</xhtml:em>*: <xhtml:code>3600</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>EventLogFlags</xhtml:em>*: <xhtml:code>3</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enable Windows NTP Client</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enable Windows NTP Server</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Global Configuration Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>AnnounceFlags</xhtml:em>*: <xhtml:code>5</xhtml:code> (Reliable Time Server).</xhtml:li>
          <xhtml:li>Force update policy on the PDC Emulator.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on the active PDC Emulator.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PdcTimeSync.ps1">Download Script: Configure-PdcTimeSync.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PdcTimeSync.ps1
# Description: Configures Windows Time Service on the PDC Emulator or default DC time settings.

Write-Host "Applying hardening: Configure NTP Time Synchronization on PDC Emulator..." -ForegroundColor Cyan

# 1. Determine if local computer is the PDC Emulator
try {
    $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PdcName = $Domain.PdcRoleOwner.Name
    $ComputerFQDN = "$env:COMPUTERNAME.$env:USERDNSDOMAIN"
    $IsPdc = ($PdcName -eq $ComputerFQDN) -or ($PdcName.Split(".")[0] -eq $env:COMPUTERNAME)
} catch {
    Write-Warning "Could not dynamically determine PDC Emulator FSMO role owner. Defaulting to NT5DS client mode."
    $IsPdc = $false
}

$W32TimeParams = "HKLM:\System\CurrentControlSet\Services\W32Time\Parameters"
$W32TimeConfig = "HKLM:\System\CurrentControlSet\Services\W32Time\Config"

if ($IsPdc) {
    Write-Host "[+] This system is the active PDC Emulator. Configuring as reliable NTP source..." -ForegroundColor Green
    
    # Configure parameters
    Set-ItemProperty -Path $W32TimeParams -Name "Type" -Value "NTP" -Type String -Force
    # Set default external NTP source (e.g. time.windows.com or local air-gapped clock)
    Set-ItemProperty -Path $W32TimeParams -Name "NtpServer" -Value "time.windows.com,0x8" -Type String -Force
    # Configure AnnounceFlags to 5 (Reliable Time Server)
    Set-ItemProperty -Path $W32TimeConfig -Name "AnnounceFlags" -Value 5 -Type DWord -Force
    
    # Apply changes to w32time service
    $Null = Start-Process w32tm -ArgumentList "/config /manualpeerlist:`"time.windows.com,0x8`" /syncfromflags:manual /reliable:yes /update" -Wait -NoNewWindow
    Write-Host "[+] System w32tm manual peer list updated to time.windows.com." -ForegroundColor Green
} else {
    Write-Host "[-] This system is NOT the PDC Emulator. Enforcing NT5DS domain hierarchy sync..." -ForegroundColor Yellow
    
    # Configure parameters
    Set-ItemProperty -Path $W32TimeParams -Name "Type" -Value "NT5DS" -Type String -Force
    Set-ItemProperty -Path $W32TimeConfig -Name "AnnounceFlags" -Value 10 -Type DWord -Force
    
    # Apply changes to w32time service
    $Null = Start-Process w32tm -ArgumentList "/config /syncfromflags:domhier /reliable:no /update" -Wait -NoNewWindow
    Write-Host "[+] System w32tm configured to synchronize from domain hierarchy." -ForegroundColor Green
}

# Restart Windows Time Service to apply settings
Restart-Service w32time -Force
Write-Host "[+] Windows Time Service (w32time) restarted." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify time synchronization status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PdcTimeSyncStatus.ps1">Download Script: Get-PdcTimeSyncStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PdcTimeSyncStatus.ps1
# Description: Audits Windows Time Service configuration on the local Domain Controller.

Write-Host "--- Auditing PDC Time Synchronization Status ---" -ForegroundColor Cyan

# 1. Determine if local computer is the PDC Emulator
try {
    $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PdcName = $Domain.PdcRoleOwner.Name
    $ComputerFQDN = "$env:COMPUTERNAME.$env:USERDNSDOMAIN"
    $IsPdc = ($PdcName -eq $ComputerFQDN) -or ($PdcName.Split(".")[0] -eq $env:COMPUTERNAME)
} catch {
    Write-Warning "Could not dynamically determine PDC Emulator FSMO role owner."
    $IsPdc = $false
}

$W32TimeParams = "HKLM:\System\CurrentControlSet\Services\W32Time\Parameters"
$W32TimeConfig = "HKLM:\System\CurrentControlSet\Services\W32Time\Config"

$TypeVal = Get-ItemProperty -Path $W32TimeParams -Name "Type" -ErrorAction SilentlyContinue
$AnnounceVal = Get-ItemProperty -Path $W32TimeConfig -Name "AnnounceFlags" -ErrorAction SilentlyContinue

$Service = Get-Service -Name w32time -ErrorAction SilentlyContinue

if ($null -eq $Service -or $Service.Status -ne "Running") {
    Write-Host "[!] VULNERABLE: Windows Time Service (w32time) is not running." -ForegroundColor Red
    exit 1
}

if ($IsPdc) {
    Write-Host "[*] Active role: PDC Emulator FSMO owner." -ForegroundColor White
    if ($TypeVal.Type -eq "NTP" -and $AnnounceVal.AnnounceFlags -eq 5) {
        Write-Host "[+] Compliant: PDC Emulator configured as reliable NTP source (Type: NTP, Announce: 5)." -ForegroundColor Green
        exit 0
    } else {
        Write-Host "[!] NON-COMPLIANT: PDC Emulator has incorrect settings (Type: $($TypeVal.Type), Announce: $($AnnounceVal.AnnounceFlags))." -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "[*] Active role: Standard Domain Controller." -ForegroundColor White
    if ($TypeVal.Type -eq "NT5DS" -and $AnnounceVal.AnnounceFlags -eq 10) {
        Write-Host "[+] Compliant: Standard Domain Controller using NT5DS domain hierarchy." -ForegroundColor Green
        exit 0
    } else {
        Write-Host "[!] NON-COMPLIANT: DC is not using standard NT5DS settings (Type: $($TypeVal.Type), Announce: $($AnnounceVal.AnnounceFlags))." -ForegroundColor Red
        exit 1
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PdcTimeSync.ps1
# Description: Configures Windows Time Service on the PDC Emulator or default DC time settings.

Write-Host "Applying hardening: Configure NTP Time Synchronization on PDC Emulator..." -ForegroundColor Cyan

# 1. Determine if local computer is the PDC Emulator
try {
    $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PdcName = $Domain.PdcRoleOwner.Name
    $ComputerFQDN = "$env:COMPUTERNAME.$env:USERDNSDOMAIN"
    $IsPdc = ($PdcName -eq $ComputerFQDN) -or ($PdcName.Split(".")[0] -eq $env:COMPUTERNAME)
} catch {
    Write-Warning "Could not dynamically determine PDC Emulator FSMO role owner. Defaulting to NT5DS client mode."
    $IsPdc = $false
}

$W32TimeParams = "HKLM:\System\CurrentControlSet\Services\W32Time\Parameters"
$W32TimeConfig = "HKLM:\System\CurrentControlSet\Services\W32Time\Config"

if ($IsPdc) {
    Write-Host "[+] This system is the active PDC Emulator. Configuring as reliable NTP source..." -ForegroundColor Green
    
    # Configure parameters
    Set-ItemProperty -Path $W32TimeParams -Name "Type" -Value "NTP" -Type String -Force
    # Set default external NTP source (e.g. time.windows.com or local air-gapped clock)
    Set-ItemProperty -Path $W32TimeParams -Name "NtpServer" -Value "time.windows.com,0x8" -Type String -Force
    # Configure AnnounceFlags to 5 (Reliable Time Server)
    Set-ItemProperty -Path $W32TimeConfig -Name "AnnounceFlags" -Value 5 -Type DWord -Force
    
    # Apply changes to w32time service
    $Null = Start-Process w32tm -ArgumentList "/config /manualpeerlist:`"time.windows.com,0x8`" /syncfromflags:manual /reliable:yes /update" -Wait -NoNewWindow
    Write-Host "[+] System w32tm manual peer list updated to time.windows.com." -ForegroundColor Green
} else {
    Write-Host "[-] This system is NOT the PDC Emulator. Enforcing NT5DS domain hierarchy sync..." -ForegroundColor Yellow
    
    # Configure parameters
    Set-ItemProperty -Path $W32TimeParams -Name "Type" -Value "NT5DS" -Type String -Force
    Set-ItemProperty -Path $W32TimeConfig -Name "AnnounceFlags" -Value 10 -Type DWord -Force
    
    # Apply changes to w32time service
    $Null = Start-Process w32tm -ArgumentList "/config /syncfromflags:domhier /reliable:no /update" -Wait -NoNewWindow
    Write-Host "[+] System w32tm configured to synchronize from domain hierarchy." -ForegroundColor Green
}

# Restart Windows Time Service to apply settings
Restart-Service w32time -Force
Write-Host "[+] Windows Time Service (w32time) restarted." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2031" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-032" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-032] Enable UEFI Secure Boot</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/enable-secure-boot.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Secure Boot is a security standard developed by members of the PC industry to help ensure that a device boots using only software that is trusted by the Original Equipment Manufacturer (OEM).</xhtml:p>
        <xhtml:p>When the PC starts, the firmware checks the signature of each piece of boot software, including UEFI firmware drivers (also known as Option ROMs), EFI applications, and the operating system. If the signatures are valid, the PC boots, and the firmware gives control to the operating system.</xhtml:p>
        <xhtml:p>For Tier 0 assets like Domain Controllers, firmware integrity is critical. If Secure Boot is disabled: 1. <xhtml:strong>Bootkits &amp; Rootkits</xhtml:strong>: Attackers with physical access or hosting infrastructure control (in virtual environments) can replace the boot manager with a malicious bootloader (bootkit) to bypass LSASS protections and all OS security controls before the Windows kernel loads. 2. <xhtml:strong>Virtualization-Based Security</xhtml:strong>: Advanced security boundaries (like LSA Protection and Device Guard) depend on hardware-rooted trust. Without UEFI Secure Boot active, virtualization-based security capabilities cannot execute with proper system measurements.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Firmware / Hypervisor Configuration (Preferred)</xhtml:h3>
        <xhtml:p>UEFI Secure Boot must be configured at the hardware or hypervisor layer:</xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Physical Servers</xhtml:strong>: Access the UEFI firmware configuration utility during POST (Delete, F2, F10, or F12) and enable <xhtml:strong>Secure Boot</xhtml:strong> in the Security settings.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hyper-V Gen 2 Virtual Machines</xhtml:strong>:</xhtml:li>
          <xhtml:li>1. Open <xhtml:strong>Hyper-V Manager</xhtml:strong>.</xhtml:li>
          <xhtml:li>2. Select the Domain Controller VM and open its <xhtml:strong>Settings</xhtml:strong>.</xhtml:li>
          <xhtml:li>3. Navigate to <xhtml:strong>Security</xhtml:strong> -&gt; check <xhtml:strong>Enable Secure Boot</xhtml:strong> -&gt; select <xhtml:strong>Microsoft Windows</xhtml:strong> template.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>VMware vSphere Virtual Machines</xhtml:strong>:</xhtml:li>
          <xhtml:li>1. Open the <xhtml:strong>vSphere Client</xhtml:strong>.</xhtml:li>
          <xhtml:li>2. Edit settings of the Domain Controller VM -&gt; go to <xhtml:strong>VM Options</xhtml:strong> -&gt; <xhtml:strong>Boot Options</xhtml:strong>.</xhtml:li>
          <xhtml:li>3. Set Firmware to <xhtml:strong>EFI</xhtml:strong> and check <xhtml:strong>Enable UEFI Secure Boot</xhtml:strong>.</xhtml:li>
        </xhtml:ul>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Secure Boot cannot be configured from within the OS using registry settings. However, you must programmatically audit the state of Secure Boot to flag non-compliant hardware.</xhtml:p>
        <xhtml:p>Run the following script to check the status of Secure Boot on the Domain Controller:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-DcSecureBoot.ps1">Download Script: Audit-DcSecureBoot.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-DcSecureBoot.ps1
# Description: Queries UEFI Secure Boot parameters and audits UEFI Secure Boot status.

Write-Host "--- Auditing UEFI Secure Boot ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Verify boot environment type
if ($env:firmware_type -eq "UEFI") {
    Write-Host "    - Boot Environment Type: UEFI" -ForegroundColor Green
} else {
    Write-Host "    - VULNERABLE: System booted in Legacy BIOS mode (CSM enabled) or firmware type is unrecognized." -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Verify Secure Boot status
try {
    # Confirm-SecureBootUEFI returns $true if Secure Boot is active, $false if disabled,
    # and throws an exception if the platform does not support UEFI or Secure Boot.
    $SecureBootState = Confirm-SecureBootUEFI -ErrorAction Stop
    
    $Color = if ($SecureBootState -eq $true) { "Green" } else { "Red" }
    Write-Host "    - Secure Boot Active: $SecureBootState" -ForegroundColor $Color
    if ($SecureBootState -eq $false) { $script:NonCompliant = $true }
} catch [System.PlatformNotSupportedException] {
    Write-Host "    - VULNERABLE: UEFI Secure Boot is not supported on this platform (Legacy BIOS mode)." -ForegroundColor Red
    $script:NonCompliant = $true
} catch {
    # If cmdlet throws unauthorized access or not enabled error
    Write-Host "    - VULNERABLE: Secure Boot is disabled in firmware or cannot be verified. Error: $($_.Exception.Message)" -ForegroundColor Red
    $script:NonCompliant = $true
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2032" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-033" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-033] Configure Secure Boot Revocations and Bootloader Updates</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-secure-boot-revocations.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>A vulnerability in the Windows Boot Manager allows an attacker with physical access or local administrative rights to bypass UEFI Secure Boot and execute unsigned code during the boot process (BlackLotus bootkit).</xhtml:p>
        <xhtml:p>To fully mitigate this threat (CVE-2023-24932), Windows update revocations must be applied to the UEFI variables (DBX list) and code integrity SVN policies must be updated. This is managed via the <xhtml:code>AvailableUpdates</xhtml:code> registry key, which instructs the OS boot manager to write the revocation variables to firmware.</xhtml:p>
        <xhtml:p>According to the latest Microsoft guidelines, the recommended trigger value for enterprise deployments to apply all security updates (including the new Windows UEFI CA 2023 certificates and boot manager updates) is <xhtml:strong>`0x5944`</xhtml:strong> (hex) / <xhtml:strong>`22852`</xhtml:strong> (decimal). As the OS processes this bitmask, the value is cleared incrementally, ending up at <xhtml:strong>`0x4000`</xhtml:strong> (hex) / <xhtml:strong>`16384`</xhtml:strong> (decimal) upon successful completion.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To configure the update triggers for the DBX and Code Integrity boot manager revocations, define Registry GPO Preferences inside the Domain Controllers GPO:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a registry item to deploy the <xhtml:code>AvailableUpdates</xhtml:code> DWORD under <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AvailableUpdates</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>22852</xhtml:code> (Decimal) or <xhtml:code>5944</xhtml:code> (Hex)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the BlackLotus mitigation update trigger:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DcSecureBootRevocations.ps1">Download Script: Set-DcSecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DcSecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Audit Script</xhtml:h3>
        <xhtml:p>Run the following script to check the status of Secure Boot revocations on the local machine:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-DcSecureBootRevocations.ps1">Download Script: Audit-DcSecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-DcSecureBootRevocations.ps1
# Description: Queries UEFI Secure Boot parameters and audits BlackLotus mitigation registry settings.

Write-Host "--- Auditing BlackLotus Mitigations ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Audit AvailableUpdates registry key
$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (Test-Path $Path) {
    $Val = Get-ItemProperty -Path $Path -Name "AvailableUpdates" -ErrorAction SilentlyContinue
    $UpdateVal = if ($Val) { $Val.AvailableUpdates } else { 0 }
    
    # Check if configured (&gt;= 0x4000 / 16384)
    if ($UpdateVal -ge 16384) {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Compliant)" -ForegroundColor Green
    } else {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Non-Compliant - DBX/SVN revocations not triggered)" -ForegroundColor Red
        $script:NonCompliant = $true
    }
} else {
    Write-Host "    - BlackLotus Revocation Updates: Registry path not found (Non-Compliant)" -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Audit UEFICA2023Status (if present)
$ServicingPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing"
if (Test-Path $ServicingPath) {
    $ServVal = Get-ItemProperty -Path $ServicingPath -Name "UEFICA2023Status" -ErrorAction SilentlyContinue
    if ($ServVal) {
        $Status = $ServVal.UEFICA2023Status
        $Color = if ($Status -eq "Updated") { "Green" } else { "Yellow" }
        Write-Host "    - UEFI CA 2023 Update Status: $Status" -ForegroundColor $Color
    }
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DcSecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2033" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-034" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-034] Configure Windows Defender Application Control</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-wdac.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in an Active Directory forest. Traditional signature-based antivirus solutions are easily bypassed by custom, compiled executables, memory injection scripts, or zero-day payloads.</xhtml:p>
        <xhtml:p>
          <xhtml:strong>Windows Defender Application Control (WDAC)</xhtml:strong> enforces a strict trust-based model for binary and script execution. By restricting the operating system to only run signed, trusted system files and administrative utilities, WDAC blocks unauthorized software, remote access tools, and custom malware. Deploying WDAC on Domain Controllers mitigates administrative credential dumping, domain compromises, and malware execution in kernel or user space.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To deploy WDAC via Group Policy, the policy XML must first be generated, compiled, and placed in a secure shared intranet network path or local path on Domain Controllers.</xhtml:p>
        <xhtml:h4>1. Generate and Compile the Policy (on a Reference Domain Controller)</xhtml:h4>
        <xhtml:p>Run the following PowerShell commands to generate the Microsoft Default Windows baseline policy: <xhtml:code />
          <xhtml:code>powershell # Generate the baseline policy XML New-CIPolicy -MultiplePolicyFormat -Level FilePublisher -FilePath "C:\WDAC\DCBaselinePolicy.xml" -UserPEs  # Compile the XML policy into a binary CIP file ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\DCBaselinePolicy.xml" -BinaryFilePath "C:\WDAC\DCBaselinePolicy.cip" </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:h4>2. Deploy the Policy via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Copy the compiled <xhtml:code>DCBaselinePolicy.cip</xhtml:code> file to a local secure directory on all target Domain Controllers (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or host it on a network share.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the local path (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or network share path.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to generate a baseline WDAC policy, enable Audit Mode, and configure local parameters.</xhtml:p>
        <xhtml:h1>Configure-DCWDACLocalPolicy.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DCWDACLocalPolicy.ps1">Download Script: Configure-DCWDACLocalPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DCWDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy for Domain Controllers, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring Domain Controller WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\DCDefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:h1>Test-DCWDACStatus.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-DCWDACStatus.ps1">Download Script: Test-DCWDACStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-DCWDACStatus.ps1
# Description: Audits the local Domain Controller to check if Code Integrity policies and HVCI are active.

Write-Host "--- Auditing Domain Controller WDAC State ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Query WMI class for Code Integrity status
try {
    $CI = Get-CimInstance -Namespace "Root\Microsoft\Windows\CI" -ClassName "MSFT_Sipolicy" -ErrorAction Stop
    if ($null -ne $CI -and $CI.Count -gt 0) {
        Write-Host "`n[+] Found $($CI.Count) active Code Integrity policies." -ForegroundColor Green
        foreach ($Policy in $CI) {
            Write-Host "    - Policy: $($Policy.FriendlyName) | ID: $($Policy.PolicyID) | Enforced: $($Policy.EnforcementMode)" -ForegroundColor Green
        }
    } else {
        Write-Host "`n[-] No active Code Integrity / WDAC policies detected via WMI." -ForegroundColor Yellow
    }
} catch {
    Write-Host "`n[-] Could not query WMI MSFT_Sipolicy. This is expected if no WDAC policies are currently deployed." -ForegroundColor Gray
}

# 2. Check Memory Integrity (HVCI) configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: One or more driver security controls are not configured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: WDAC driver settings and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DCWDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy for Domain Controllers, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring Domain Controller WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\DCDefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2034" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-156" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-156] Configure Early Launch Antimalware (ELAM) Policy on Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0). <xhtml:em>(For Privileged Access Workstations, refer to [REQ-PAW-014](../07-paws/configure-elam.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-028](../08-endpoints/configure-elam.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-elam.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory Domain Controllers serve as the root of trust (Tier 0) for the entire enterprise directory. Early-stage boot integrity is critical to prevent kernel-level compromise before security subsystems initialize.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) with Domain Admin credentials.</xhtml:li>
          <xhtml:li>Edit the baseline Domain Controller hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Early Launch Antimalware</xhtml:code>
          </xhtml:li>
          <xhtml:li>In the right pane, double-click <xhtml:strong>Boot-Start Driver Initialization Policy</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the <xhtml:strong>Choose the boot-start drivers that can be initialized</xhtml:strong> dropdown, select:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Good, unknown and bad but critical</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the <xhtml:strong>Domain Controllers</xhtml:strong> Organizational Unit (<xhtml:code>OU=Domain Controllers,DC=domain,DC=com</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally on Domain Controllers to configure the ELAM boot-start driver policy.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DcElamPolicy.ps1">Download Script: Configure-DcElamPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DcElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver initialization policy on Domain Controllers.

Write-Host "Applying ELAM Boot-Start driver initialization policy on Domain Controller..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 3 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good, unknown and bad but critical' (Value = 3)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DcElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver initialization policy on Domain Controllers.

Write-Host "Applying ELAM Boot-Start driver initialization policy on Domain Controller..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 3 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good, unknown and bad but critical' (Value = 3)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2156" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-157" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-157] UEFI Firmware Security Hardening on Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (both physical bare-metal enterprise servers and hypervisor-hosted virtual machines). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-005](../07-paws/configure-uefi-security.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-013](../08-endpoints/configure-uefi-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-uefi-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers are Tier 0 crown jewels that store the directory database (<xhtml:code>NTDS.dit</xhtml:code>), Kerberos key distribution services (<xhtml:code>KDC</xhtml:code>), and enterprise authentication secrets. If the underlying platform firmware or virtual machine boot configuration is compromised, an attacker can subvert all operating system and hypervisor defenses before the Windows kernel loads.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Hardware &amp; Hypervisor Firmware Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>For Physical Servers (Dell PowerEdge, HPE ProLiant, Lenovo ThinkSystem):</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Restart the server and enter system setup during POST (typically F2 on Dell, F9 on HPE, F1 on Lenovo).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Security Settings</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set a strong </xhtml:em>
            <xhtml:em>System Password</xhtml:em>
            <xhtml:em> / </xhtml:em>
            <xhtml:em>Setup Password</xhtml:em>* (Administrator/Supervisor). Record it in the Tier 0 credential vault.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Verify </xhtml:em>
            <xhtml:em>TPM 2.0 Security</xhtml:em>
            <xhtml:em> is </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> and </xhtml:em>
            <xhtml:em>Activated</xhtml:em>* with SHA-256 PCR bank.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Enable </xhtml:em>
            <xhtml:em>Memory Overwrite Request (MOR)</xhtml:em>* or Memory Clearing on boot.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Boot Settings</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set </xhtml:em>
            <xhtml:em>Boot Mode</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>UEFI</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Disable </xhtml:em>
            <xhtml:em>Legacy BIOS / CSM</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set </xhtml:em>
            <xhtml:em>Boot Sequence</xhtml:em>* to primary internal storage (RAID/SAN). Disable USB and Network PXE boot options.</xhtml:li>
          <xhtml:li>* Enable password prompt on Boot Override Menu (F11/F12).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Processor / Virtualization Settings</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Enable </xhtml:em>
            <xhtml:em>Intel Virtualization Technology (VT-x)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD-V</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Enable </xhtml:em>
            <xhtml:em>Intel VT for Directed I/O (VT-d)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD IOMMU</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Secure Boot Settings</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Enable </xhtml:em>
            <xhtml:em>Secure Boot</xhtml:em>
            <xhtml:em>. Ensure Secure Boot Mode is set to </xhtml:em>
            <xhtml:em>Deployed Mode</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Firmware Rollback</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Enable </xhtml:em>
            <xhtml:em>BIOS Flash Protection</xhtml:em>
            <xhtml:em> / </xhtml:em>
            <xhtml:em>Rollback Prevention</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Baseboard Management Controller (BMC / iDRAC / iLO)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Navigate to BMC network settings -&gt; Disable </xhtml:em>
            <xhtml:em>IPMI over LAN</xhtml:em>* (UDP 623).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure web server enforces </xhtml:em>
            <xhtml:em>HTTPS (TLS 1.2/1.3)</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Detach and disable </xhtml:em>
            <xhtml:em>Virtual Media</xhtml:em>*.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>For Virtual Domain Controllers (Hyper-V Gen 2 / VMware ESXi):</xhtml:h4>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Hyper-V</xhtml:strong>:</xhtml:li>
          <xhtml:li>1. Open <xhtml:strong>Hyper-V Manager</xhtml:strong>, select the Domain Controller VM, and open <xhtml:strong>Settings</xhtml:strong>.</xhtml:li>
          <xhtml:li>2. Navigate to <xhtml:strong>Security</xhtml:strong> -&gt; check <xhtml:strong>Enable Secure Boot</xhtml:strong> (Template: <xhtml:strong>Microsoft Windows</xhtml:strong>).</xhtml:li>
          <xhtml:li>3. Under <xhtml:strong>Security Support</xhtml:strong>, check <xhtml:strong>Enable Trusted Platform Module</xhtml:strong> (vTPM).</xhtml:li>
          <xhtml:li>4. Navigate to <xhtml:strong>Firmware</xhtml:strong> -&gt; verify boot order has the virtual hard drive (<xhtml:code>.vhdx</xhtml:code>) at the top, and remove network adapter and virtual DVD drive from the boot list.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>VMware vSphere</xhtml:strong>:</xhtml:li>
          <xhtml:li>1. Open the <xhtml:strong>vSphere Client</xhtml:strong>, edit VM settings.</xhtml:li>
          <xhtml:li>2. Under <xhtml:strong>VM Options</xhtml:strong> -&gt; <xhtml:strong>Boot Options</xhtml:strong> -&gt; set Firmware to <xhtml:strong>EFI</xhtml:strong> and check <xhtml:strong>Enable UEFI Secure Boot</xhtml:strong>.</xhtml:li>
          <xhtml:li>3. Under <xhtml:strong>Virtual Hardware</xhtml:strong> -&gt; click <xhtml:strong>Add New Device</xhtml:strong> -&gt; select <xhtml:strong>Trusted Platform Module</xhtml:strong> (vTPM).</xhtml:li>
          <xhtml:li>4. Remove or disconnect virtual CD/DVD drives and disable network boot in VM boot options.</xhtml:li>
        </xhtml:ul>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Remediation &amp; OS Boot Hardening</xhtml:h3>
        <xhtml:p>Run the following script to configure OS-level boot parameters (disabling Windows Fast Startup, ensuring Device Guard platform flags), detect whether the Domain Controller is running on physical hardware or a virtual hypervisor, and display appropriate firmware configuration guidance.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DcUefiSecurity.ps1">Download Script: Set-DcUefiSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DcUefiSecurity.ps1
# Description: Configures OS-level boot parameters and audits platform firmware configuration on Domain Controllers.

Write-Host "--- Configuring Domain Controller UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features configured (Value = 1)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Server Environment (Physical vs Virtual)
$ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction SilentlyContinue
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue

Write-Host "`nPlatform Environment Detection:" -ForegroundColor Cyan
Write-Host "  Model:        $($ComputerSystem.Model)" -ForegroundColor White
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($ComputerSystem.Model -match "Virtual Machine|VMware|KVM|Hyper-V") {
    Write-Host "  [i] Virtual Domain Controller detected." -ForegroundColor Yellow
    Write-Host "      Ensure VM is Generation 2 (UEFI) with Secure Boot enabled and a virtual TPM (vTPM 2.0) attached." -ForegroundColor Gray
    Write-Host "      Hyper-V PowerShell: Set-VMFirmware -VMName '&lt;DC&gt;' -EnableSecureBoot On -SecureBootTemplate MicrosoftWindows" -ForegroundColor Gray
    Write-Host "      Hyper-V PowerShell: Enable-VMTPM -VMName '&lt;DC&gt;'" -ForegroundColor Gray
} else {
    Write-Host "  [i] Physical Bare-Metal Server detected." -ForegroundColor Yellow
    Write-Host "      Ensure BIOS supervisor password is set, CSM is disabled, boot order is locked to RAID," -ForegroundColor Gray
    Write-Host "      VT-x/VT-d is enabled, and Out-of-Band BMC (iDRAC/iLO) has IPMI over LAN disabled." -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DcUefiSecurity.ps1
# Description: Configures OS-level boot parameters and audits platform firmware configuration on Domain Controllers.

Write-Host "--- Configuring Domain Controller UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features configured (Value = 1)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Server Environment (Physical vs Virtual)
$ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction SilentlyContinue
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue

Write-Host "`nPlatform Environment Detection:" -ForegroundColor Cyan
Write-Host "  Model:        $($ComputerSystem.Model)" -ForegroundColor White
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($ComputerSystem.Model -match "Virtual Machine|VMware|KVM|Hyper-V") {
    Write-Host "  [i] Virtual Domain Controller detected." -ForegroundColor Yellow
    Write-Host "      Ensure VM is Generation 2 (UEFI) with Secure Boot enabled and a virtual TPM (vTPM 2.0) attached." -ForegroundColor Gray
    Write-Host "      Hyper-V PowerShell: Set-VMFirmware -VMName '&lt;DC&gt;' -EnableSecureBoot On -SecureBootTemplate MicrosoftWindows" -ForegroundColor Gray
    Write-Host "      Hyper-V PowerShell: Enable-VMTPM -VMName '&lt;DC&gt;'" -ForegroundColor Gray
} else {
    Write-Host "  [i] Physical Bare-Metal Server detected." -ForegroundColor Yellow
    Write-Host "      Ensure BIOS supervisor password is set, CSM is disabled, boot order is locked to RAID," -ForegroundColor Gray
    Write-Host "      VT-x/VT-d is enabled, and Out-of-Band BMC (iDRAC/iLO) has IPMI over LAN disabled." -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2157" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-158" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-158] Harden DMA and Physical Security for Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (both physical bare-metal enterprise servers and hypervisor-hosted virtual machines). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-011](../07-paws/harden-dma-and-physical-security.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-017](../08-endpoints/harden-dma-and-physical-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/harden-dma-and-physical-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers represent Tier 0 identity stores hosting the directory database (<xhtml:code>NTDS.dit</xhtml:code>), Kerberos Ticket Granting Service keys (<xhtml:code>krbtgt</xhtml:code>), and password hashes for all enterprise principals. While enterprise servers reside in datacenters or branch office wiring closets, physical access threats remain a critical attack vector:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Direct Memory Access (DMA) Threat Vectors</xhtml:strong>: Hot-plug expansion ports and external peripheral interfaces (such as PCIe hot-plug slots, Thunderbolt, USB4, or external storage expansion cards) permit connected hardware to bypass operating system access controls and perform direct read/write operations against physical DRAM. Attackers utilizing physical DMA consoles (e.g., PCILeech or malicious PCIe expansion cards inserted into physical server chassis) can dump LSASS memory and extract volatile Kerberos keys:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Device Setup Class Lockdown</xhtml:em>*: Disabling the SBP-2 protocol class (<xhtml:code>{d48179be-ec20-11d1-b6b8-00c04fa372a7}</xhtml:code>) and IEEE 1394 host controller class (<xhtml:code>{6bdd1fc1-810f-11d0-bec7-08002be2092f}</xhtml:code>) prevents Windows Server from mounting legacy FireWire storage devices.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hardware ID Blocking</xhtml:em>*: Explicitly blocking hardware IDs <xhtml:code>PCI\CC_0C0A</xhtml:code> (Thunderbolt), <xhtml:code>PCI\CC_0C0010</xhtml:code> (FireWire), <xhtml:code>PCI\CC_0607</xhtml:code> (CardBus), and <xhtml:code>PCI\CC_0605</xhtml:code> (PCMCIA) prevents the installation of unapproved expansion controllers at the hardware bus layer.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>BitLocker DMA Under Lock</xhtml:em>*: Enforcing <xhtml:code>DisableExternalDMAUnderLock</xhtml:code> blocks DMA device enumeration when the server console is locked, mitigating drive-by hardware attacks on unattended consoles.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Kernel DMA Protection Enforcement</xhtml:em>*: Enforcing <xhtml:code>DeviceEnumerationPolicy = 0</xhtml:code> (Block all) guarantees that any peripheral device whose drivers do not explicitly support IOMMU DMA remapping is strictly blocked from executing DMA memory transfers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Cold Boot &amp; Standby Attacks</xhtml:strong>: In standard standby sleep states (S1-S3), system RAM remains powered and unencrypted. If an attacker gains physical access to a server in a standby state, they can execute cold-boot extraction or memory analysis to harvest sensitive directory keys. Domain Controllers must operate continuously in full runtime execution states. Disabling standby sleep states forces servers to remain fully operational or enter clean shutdown, ensuring BitLocker encryption keys are sealed by the TPM 2.0 module. Enforcing wake password verification guarantees that any power-state transition requires re-authentication.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Physical USB Exfiltration of Directory Databases</xhtml:strong>: Rogue insiders or unauthorized datacenter personnel with physical console access can insert USB flash drives to exfiltrate <xhtml:code>ntds.dit</xhtml:code>, Active Directory backups, or system state data. Enforcing <xhtml:code>RDVDenyWriteAccess = 1</xhtml:code> prevents writing to removable drives unless protected by BitLocker, while <xhtml:code>RDVDenyCrossOrg = 0</xhtml:code> eliminates unauthorized cross-organization exceptions.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Domain Controllers GPO (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code> or <xhtml:code>GPO_Hardening_DC</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>1. Power Management (Disable Standby &amp; Require Wake Password)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Power Management\Sleep Settings</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow standby states (S1-S3) when sleeping (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Allow standby states (S1-S3) when sleeping (on battery)</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Require a password when a computer wakes (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Require a password when a computer wakes (on battery)</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
        </xhtml:p>
        <xhtml:h4>2. BitLocker Removable Storage &amp; DMA</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Disable new DMA devices when this computer is locked` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em />
        </xhtml:p>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption\Removable Data Drives</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Deny write access to removable drives not protected by BitLocker` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Check <xhtml:strong>Do not allow write access to devices configured in another organization</xhtml:strong> -&gt; <xhtml:strong>Disabled</xhtml:strong> (value 0 / False)</xhtml:p>
        <xhtml:h4>3. Device Installation Restrictions (Block SBP-2, 1394, Thunderbolt, and PCI Bridges)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Device Installation\Device Installation Restrictions</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Prevent installation of devices using drivers that match these device setup classes` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Click <xhtml:strong>Show...</xhtml:strong> and enter: <xhtml:em> `{d48179be-ec20-11d1-b6b8-00c04fa372a7}` </xhtml:em>
          <xhtml:code>{6bdd1fc1-810f-11d0-bec7-08002be2092f}</xhtml:code>
          <xhtml:em> Check </xhtml:em>
          <xhtml:em>Also apply to matching devices that are already installed</xhtml:em>
          <xhtml:em> -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (value 1 / True) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Prevent installation of devices that match any of these device IDs</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> Click </xhtml:em>
          <xhtml:em>Show...</xhtml:em>
          <xhtml:em> and enter: </xhtml:em>
          <xhtml:code>PCI\CC_0C0A</xhtml:code>
          <xhtml:em> `PCI\CC_0C0010` </xhtml:em>
          <xhtml:code>PCI\CC_0607</xhtml:code>
          <xhtml:em> `PCI\CC_0605` </xhtml:em> Check <xhtml:strong>Also apply to matching devices that are already installed</xhtml:strong> -&gt; <xhtml:strong>Enabled</xhtml:strong> (value 1 / True)</xhtml:p>
        <xhtml:h4>4. Kernel DMA Protection (Block All)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Enable Kernel DMA Protection` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Enumeration policy</xhtml:strong>: Set to <xhtml:strong>Block all</xhtml:strong> (value 0)</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on the Domain Controller to apply DMA, Sleep, Device Restriction, and BitLocker USB registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DcDMAPhysicalSecurity.ps1">Download Script: Configure-DcDMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DcDMAPhysicalSecurity.ps1
# Description: Hardens local registry keys on Domain Controllers to mitigate DMA attacks, disable standby sleep states, enforce wake password, restrict device classes/IDs, and block unencrypted USB writing.

Write-Host "Applying Domain Controller DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Classes and Hardware IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String
Set-ItemProperty -Path $DenyClassPath -Name "2" -Value "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" -Type String

$DenyIdPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIdPath)) {
    New-Item -Path $DenyIdPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIdPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "3" -Value "PCI\CC_0607" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "4" -Value "PCI\CC_0605" -Type String
Write-Host "[+] Device installation blocks for SBP-2, 1394 host controllers, Thunderbolt, and PCI bridges enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "Domain Controller DMA and physical security settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local Domain Controller DMA and physical security configuration:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-DcDMAPhysicalSecurity.ps1">Download Script: Test-DcDMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-DcDMAPhysicalSecurity.ps1
# Description: Audits local registry configuration for standby settings, wake password, DMA protection under lock, USB restrictions, and blocked device classes/IDs on Domain Controllers.

Write-Host "--- Auditing Domain Controller DMA and Physical Security ---" -ForegroundColor Cyan
$isCompliant = $true

# 1. Audit Standby Settings
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
$AcSleep = Get-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcSleep = Get-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcSleepVal = if ($AcSleep) { $AcSleep.ACSettingIndex } else { 1 }
$DcSleepVal = if ($DcSleep) { $DcSleep.DCSettingIndex } else { 1 }

$AcSleepColor = if ($AcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }
$DcSleepColor = if ($DcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Standby Sleep State (Plugged In) Setting: $($AcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $AcSleepColor
Write-Host "    - Standby Sleep State (On Battery) Setting: $($DcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $DcSleepColor

# 2. Audit Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
$AcWake = Get-ItemProperty -Path $WakePath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcWake = Get-ItemProperty -Path $WakePath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcWakeVal = if ($AcWake) { $AcWake.ACSettingIndex } else { 0 }
$DcWakeVal = if ($DcWake) { $DcWake.DCSettingIndex } else { 0 }

$AcWakeColor = if ($AcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }
$DcWakeColor = if ($DcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Wake Password Required (Plugged In): $($AcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $AcWakeColor
Write-Host "    - Wake Password Required (On Battery): $($DcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $DcWakeColor

# 3. Audit BitLocker Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
$DmaLock = Get-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -ErrorAction SilentlyContinue
$DmaLockVal = if ($DmaLock) { $DmaLock.DisableExternalDMAUnderLock } else { 0 }
$DmaLockColor = if ($DmaLockVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$CrossOrg = Get-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -ErrorAction SilentlyContinue
$CrossOrgVal = if ($CrossOrg) { $CrossOrg.RDVDenyCrossOrg } else { 1 }
$CrossOrgColor = if ($CrossOrgVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
$UsbWrite = Get-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -ErrorAction SilentlyContinue
$UsbWriteVal = if ($UsbWrite) { $UsbWrite.RDVDenyWriteAccess } else { 0 }
$UsbWriteColor = if ($UsbWriteVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Disable DMA Under Lock: $($DmaLockVal) (Required = 1)" -ForegroundColor $DmaLockColor
Write-Host "    - USB Deny Cross Org Removable Drives: $($CrossOrgVal) (Required = 0)" -ForegroundColor $CrossOrgColor
Write-Host "    - USB Unencrypted Write Block: $($UsbWriteVal) (Required = 1)" -ForegroundColor $UsbWriteColor

# 4. Audit Device Restriction Settings
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
$DenyDev = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -ErrorAction SilentlyContinue
$DenyDevVal = if ($DenyDev) { $DenyDev.DenyDeviceClasses } else { 0 }
$DenyDevColor = if ($DenyDevVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$DenyId = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -ErrorAction SilentlyContinue
$DenyIdVal = if ($DenyId) { $DenyId.DenyDeviceIDs } else { 0 }
$DenyIdColor = if ($DenyIdVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Prevent Device Setup Class Installation: $($DenyDevVal) (Required = 1)" -ForegroundColor $DenyDevColor
Write-Host "    - Prevent Device ID Installation: $($DenyIdVal) (Required = 1)" -ForegroundColor $DenyIdColor

$DenyClassPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses"
$Sbp2 = Get-ItemProperty -Path $DenyClassPath -Name "1" -ErrorAction SilentlyContinue
$Sbp2Val = if ($Sbp2) { $Sbp2."1" } else { "" }
$Sbp2Color = if ($Sbp2Val -eq "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { "Green" } else { $isCompliant = $false; "Red" }

$Host1394 = Get-ItemProperty -Path $DenyClassPath -Name "2" -ErrorAction SilentlyContinue
$Host1394Val = if ($Host1394) { $Host1394."2" } else { "" }
$Host1394Color = if ($Host1394Val -eq "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked SBP-2 Setup Class: '$($Sbp2Val)' (Required = '{d48179be-ec20-11d1-b6b8-00c04fa372a7}')" -ForegroundColor $Sbp2Color
Write-Host "    - Blocked 1394 Host Setup Class: '$($Host1394Val)' (Required = '{6bdd1fc1-810f-11d0-bec7-08002be2092f}')" -ForegroundColor $Host1394Color

$DenyIdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs"
$DId1 = Get-ItemProperty -Path $DenyIdPath -Name "1" -ErrorAction SilentlyContinue
$DId1Val = if ($DId1) { $DId1."1" } else { "" }
$DId1Color = if ($DId1Val -eq "PCI\CC_0C0A") { "Green" } else { $isCompliant = $false; "Red" }

$DId2 = Get-ItemProperty -Path $DenyIdPath -Name "2" -ErrorAction SilentlyContinue
$DId2Val = if ($DId2) { $DId2."2" } else { "" }
$DId2Color = if ($DId2Val -eq "PCI\CC_0C0010") { "Green" } else { $isCompliant = $false; "Red" }

$DId3 = Get-ItemProperty -Path $DenyIdPath -Name "3" -ErrorAction SilentlyContinue
$DId3Val = if ($DId3) { $DId3."3" } else { "" }
$DId3Color = if ($DId3Val -eq "PCI\CC_0607") { "Green" } else { $isCompliant = $false; "Red" }

$DId4 = Get-ItemProperty -Path $DenyIdPath -Name "4" -ErrorAction SilentlyContinue
$DId4Val = if ($DId4) { $DId4."4" } else { "" }
$DId4Color = if ($DId4Val -eq "PCI\CC_0605") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked Device ID PCI\CC_0C0A: '$($DId1Val)' (Required = 'PCI\CC_0C0A')" -ForegroundColor $DId1Color
Write-Host "    - Blocked Device ID PCI\CC_0C0010: '$($DId2Val)' (Required = 'PCI\CC_0C0010')" -ForegroundColor $DId2Color
Write-Host "    - Blocked Device ID PCI\CC_0607: '$($DId3Val)' (Required = 'PCI\CC_0607')" -ForegroundColor $DId3Color
Write-Host "    - Blocked Device ID PCI\CC_0605: '$($DId4Val)' (Required = 'PCI\CC_0605')" -ForegroundColor $DId4Color

# 5. Audit Kernel DMA Protection Setting
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
$EnumPol = Get-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -ErrorAction SilentlyContinue
$EnumPolVal = if ($EnumPol) { $EnumPol.DeviceEnumerationPolicy } else { 2 }
$EnumPolColor = if ($EnumPolVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Kernel DMA Protection Policy: $($EnumPolVal) (Required = 0 [Block all])" -ForegroundColor $EnumPolColor

# 6. Final Compliance Assessment
if ($isCompliant) {
    Write-Host "[+] Audit Result: SECURE - Domain Controller DMA and physical security controls are fully compliant." -ForegroundColor Green
} else {
    Write-Host "[-] Audit Result: VULNERABLE - One or more Domain Controller DMA or physical security settings do not meet baseline requirements." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DcDMAPhysicalSecurity.ps1
# Description: Hardens local registry keys on Domain Controllers to mitigate DMA attacks, disable standby sleep states, enforce wake password, restrict device classes/IDs, and block unencrypted USB writing.

Write-Host "Applying Domain Controller DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Classes and Hardware IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String
Set-ItemProperty -Path $DenyClassPath -Name "2" -Value "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" -Type String

$DenyIdPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIdPath)) {
    New-Item -Path $DenyIdPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIdPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "3" -Value "PCI\CC_0607" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "4" -Value "PCI\CC_0605" -Type String
Write-Host "[+] Device installation blocks for SBP-2, 1394 host controllers, Thunderbolt, and PCI bridges enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "Domain Controller DMA and physical security settings applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2158" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-159" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-159] Disable Windows Script Host and Remap Scripting Extensions on Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers and Member Servers (Tier 0 Identity Infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to [REQ-PAW-034](../07-paws/disable-windows-script-host.md); for Tier 2 Client Workstations, refer to [REQ-END-034](../08-endpoints/disable-windows-script-host.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/disable-windows-script-host.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers host the Active Directory directory database (<xhtml:code>NTDS.dit</xhtml:code>), Kerberos ticket-granting service keys (<xhtml:code>krbtgt</xhtml:code>), and credentials for all domain identities. Protecting these Tier 0 identity stores requires aggressive operating system minimization and the systematic neutralization of Living-off-the-Land Binaries (LOLBins / LOLBAS) that adversaries leverage during post-exploitation, lateral movement, and defense evasion:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Mitigation of LOLBin Abuse on Critical Servers</xhtml:strong>: Windows Script Host binaries (<xhtml:code>cscript.exe</xhtml:code> and <xhtml:code>wscript.exe</xhtml:code>) execute legacy VBScript (<xhtml:code>vbscript.dll</xhtml:code>) and JScript (<xhtml:code>jscript.dll</xhtml:code>) engines. Threat actors targeting Domain Controllers frequently invoke <xhtml:code>cscript.exe</xhtml:code> or <xhtml:code>mshta.exe</xhtml:code> to execute obfuscated staging scripts, query Active Directory via legacy ADSI/WMI interfaces, or execute memory injection routines while attempting to evade standard binary application allowlisting (MITRE ATT&amp;CK T1059.005, T1059.007, T1218).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Elimination of Untrusted Script Execution</xhtml:strong>: Disabling WSH system-wide via the <xhtml:code>Enabled = 0</xhtml:code> registry setting prevents the execution of all <xhtml:code>.vbs</xhtml:code>, <xhtml:code>.vbe</xhtml:code>, <xhtml:code>.js</xhtml:code>, <xhtml:code>.jse</xhtml:code>, <xhtml:code>.wsf</xhtml:code>, and <xhtml:code>.wsh</xhtml:code> files through the primary scripting host, returning an immediate administrative blocking error.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Comprehensive 64-Bit and 32-Bit WOW6432Node Coverage</xhtml:strong>: In 64-bit Windows Server environments, threat actors often invoke 32-bit binaries (<xhtml:code>%SystemRoot%\SysWOW64\cscript.exe</xhtml:code> or <xhtml:code>wscript.exe</xhtml:code>) to evade 64-bit security monitoring tools and API hooks. Configuring <xhtml:code>Enabled = 0</xhtml:code> and <xhtml:code>TrustPolicy = 2</xhtml:code> across both the native 64-bit registry branch (<xhtml:code>HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>) and the 32-bit subsystem branch (<xhtml:code>HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>) closes this evasion vector.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>TrustPolicy Hardening</xhtml:strong>: Setting <xhtml:code>TrustPolicy = 2</xhtml:code> enforces restrictions that disallow untrusted scripts system-wide, establishing defense-in-depth even if individual registry keys are tampered with.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Accidental Double-Click Prevention</xhtml:strong>: Remapping legacy scripting extensions (<xhtml:code>.vbs</xhtml:code>, <xhtml:code>.vbe</xhtml:code>, <xhtml:code>.js</xhtml:code>, <xhtml:code>.jse</xhtml:code>, <xhtml:code>.wsf</xhtml:code>, <xhtml:code>.wsh</xhtml:code>, <xhtml:code>.hta</xhtml:code>) to <xhtml:code>txtfile</xhtml:code> (<xhtml:code>notepad.exe</xhtml:code>) ensures that if an administrator inspects an administrative script or diagnostic file on the DC console, opening the file in Windows Explorer displays plain text in Notepad rather than silently triggering code execution.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Disable WSH via GPO Computer Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Domain Controller GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong> for the native 64-bit hive:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong> for <xhtml:code>TrustPolicy</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a third <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 disablement:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a fourth <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 TrustPolicy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Disable WSH in User Configuration Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Remap Script File Extensions to Notepad</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Control Panel Settings\Folder Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click and select <xhtml:strong>New -&gt; Open With</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>File Extension</xhtml:em>*: <xhtml:code>vbs</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Associated Program</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\notepad.exe</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set as default</xhtml:em>*: Check</xhtml:li>
          <xhtml:li>Repeat for <xhtml:code>vbe</xhtml:code>, <xhtml:code>js</xhtml:code>, <xhtml:code>jse</xhtml:code>, <xhtml:code>wsf</xhtml:code>, <xhtml:code>wsh</xhtml:code>, and <xhtml:code>hta</xhtml:code>.</xhtml:li>
          <xhtml:li>Alternatively, configure system-wide registry preferences under <xhtml:code>HKLM\SOFTWARE\Classes\.&lt;ext&gt;</xhtml:code> setting the default string value to <xhtml:code>txtfile</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry settings to disable WSH and remap associations.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-DcWsh.ps1">Download Script: Disable-DcWsh.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-DcWsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad on Domain Controllers.

Write-Host "Applying Windows Script Host and file association hardening for Domain Controllers..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green
Write-Host "[i] Note: Software Licensing Management Tool (slmgr.vbs) requires ADBA or KMS. Use Get-CimInstance SoftwareLicensingProduct for querying status." -ForegroundColor Yellow</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the WSH configuration state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DcWshStatus.ps1">Download Script: Get-DcWshStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DcWshStatus.ps1
# Description: Audits Windows Script Host registry state across 64-bit and 32-bit hives and script file extension association handlers on Domain Controllers.

Write-Host "--- Auditing Windows Script Host Hardening on Domain Controllers ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# 1. Audit WSH Registry settings in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (Test-Path $RegistryHklm) {
    $ValHklm = (Get-ItemProperty -Path $RegistryHklm -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
    if ($ValHklm -eq 0) {
        Write-Host "    - HKLM WSH Enabled: 0 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH is enabled or not configured (Value: '$($ValHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }

    $TrustHklm = (Get-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
    if ($TrustHklm -eq 2) {
        Write-Host "    - HKLM WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH TrustPolicy is not set to 2 (Value: '$($TrustHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - VULNERABLE: HKLM WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 2. Audit WSH Registry settings in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (Test-Path $RegistryWow64) {
        $ValWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
        if ($ValWow64 -eq 0) {
            Write-Host "    - WOW6432Node WSH Enabled: 0 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH is enabled or not configured (Value: '$($ValWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }

        $TrustWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
        if ($TrustWow64 -eq 2) {
            Write-Host "    - WOW6432Node WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH TrustPolicy is not set to 2 (Value: '$($TrustWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: WOW6432Node WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# 3. Audit file associations
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    if (Test-Path $ProgIdPath) {
        $Handler = (Get-ItemProperty -Path $ProgIdPath -Name "" -ErrorAction SilentlyContinue).""
        if ($Handler -eq "txtfile" -or $Handler -match "notepad") {
            Write-Host "    - Extension .$Ext Handler: $Handler (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: Extension .$Ext Handler is '$($Handler)' (Expected: txtfile/notepad)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: Extension .$Ext Class Registry key not found." -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

if ($script:Vulnerable) {
    Write-Host "[-] Audit Result: VULNERABLE - Windows Script Host hardening controls on Domain Controller do not meet baseline requirements." -ForegroundColor Red
} else {
    Write-Host "[+] Audit Result: SECURE - Windows Script Host hardening controls on Domain Controller are fully compliant." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-DcWsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad on Domain Controllers.

Write-Host "Applying Windows Script Host and file association hardening for Domain Controllers..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green
Write-Host "[i] Note: Software Licensing Management Tool (slmgr.vbs) requires ADBA or KMS. Use Get-CimInstance SoftwareLicensingProduct for querying status." -ForegroundColor Yellow</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2159" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-160" severity="high" weight="10.0" selected="false">
      <title>[REQ-DC-160] Configure Event Log Maximum File Sizes and Retention Policies on Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>02-domain-controllers/configure-event-log-sizes.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory Domain Controllers are the highest-value targets (Tier 0) in an enterprise forest. In addition to serving as the central authentication authority, Domain Controllers continuously process authentication requests, Kerberos ticket issuances, directory service modifications, and directory replication.</xhtml:p>
        <xhtml:p>When comprehensive security audit policies are enforced on Domain Controllers (such as Kerberos Service Ticket operations [Event ID 4769], Account Logon events [Event ID 4768/4771], Directory Service Object Access [Event ID 4662], and Group Membership changes [Event ID 4728/4738]), Domain Controllers generate between 500 MB and multiple gigabytes of security telemetry daily.</xhtml:p>
        <xhtml:p>Default event log capacities (20 MB for standard channels, 16 MB to 32 MB for role channels) roll over in a matter of minutes to hours during production load. This creates severe security vulnerabilities: 1. <xhtml:strong>Mitigation of Log-Flushing Attacks</xhtml:strong>: Adversaries executing high-frequency attacks (e.g., Kerberoasting, AS-REP Roasting, password spraying, or DCSync via <xhtml:code>DsGetNCChanges</xhtml:code>) frequently attempt to "flush" the Security log by generating floods of benign authentication or LDAP requests to overwrite compromise indicators before detection. Expanding the Security log to <xhtml:strong>4 GB</xhtml:strong> (<xhtml:code>4,194,304 KB</xhtml:code>) provides a resilient on-box buffer that retains weeks of forensic evidence even under heavy attack activity. 2. <xhtml:strong>Preservation of System and Replication Diagnostics</xhtml:strong>: Domain Controllers log extensive Netlogon, KDC, DNS, DFS Replication, and NTDS replication events into the <xhtml:strong>System</xhtml:strong>, <xhtml:strong>Directory Service</xhtml:strong>, <xhtml:strong>DNS Server</xhtml:strong>, and <xhtml:strong>DFS Replication</xhtml:strong> event channels. Allocating <xhtml:strong>256 MB</xhtml:strong> to System, Directory Service, and DNS Server logs prevents replication failures and tombstone synchronization issues from being overwritten during diagnostic troubleshooting. 3. <xhtml:strong>64 KB Boundary Alignment</xhtml:strong>: The Windows Event Log service allocates memory in 64 KB blocks. Configured sizes must be exact integer multiples of 64 (<xhtml:code>SizeKB % 64 == 0</xhtml:code>). Non-aligned values will be automatically truncated or rounded by the operating system (<xhtml:code>4,194,304 / 64 = 65,536</xhtml:code>; <xhtml:code>262,144 / 64 = 4,096</xhtml:code>; <xhtml:code>131,072 / 64 = 2,048</xhtml:code>; <xhtml:code>32,768 / 64 = 512</xhtml:code>). 4. <xhtml:strong>Retention Policy</xhtml:strong>: Enforcing retention method <xhtml:code>0</xhtml:code> (GPO: <xhtml:code>Disabled</xhtml:code> / Overwrite events as needed) guarantees that new security audits are continuously recorded rather than halted when log capacity is reached.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the core Event Log Administrative Template policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Application</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>131072</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>4194304</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Setup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>32768</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>262144</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Configure Active Directory role-specific channels via Group Policy Preferences (Registry):</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\Directory Service</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>MaxSize</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>268435456</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\Directory Service</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>Retention</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\DNS Server</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>MaxSize</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>268435456</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\DNS Server</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>Retention</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\DFS Replication</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>MaxSize</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>134217728</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add </xhtml:em>
            <xhtml:em>Registry Item</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Action: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Hive: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Key Path: <xhtml:code>SYSTEM\CurrentControlSet\Services\EventLog\DFS Replication</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Name: <xhtml:code>Retention</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Type: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Value Data: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the Domain Controllers OU and verify replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally on Domain Controllers to configure the event log maximum sizes and retention policies:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DcEventLogSizes.ps1">Download Script: Configure-DcEventLogSizes.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-DcEventLogSizes.ps1
# Description: Configures Event Log Maximum File Sizes and Retention Policies on Domain Controllers.

Write-Host "Configuring Event Log Maximum File Sizes and Retention Policies on Domain Controllers..." -ForegroundColor Cyan

# 1. Core Channels via Policy Registry Branch (values in KB)
if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "MaxSize" -Value 131072 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "MaxSize" -Value 4194304 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "MaxSize" -Value 32768 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "MaxSize" -Value 262144 -Type DWord -Force

# 2. Active Directory Role Channels via Service Registry Branch (values in bytes)
$RoleChannels = @(
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service"; MaxSizeBytes = 268435456 },
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DNS Server"; MaxSizeBytes = 268435456 },
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DFS Replication"; MaxSizeBytes = 134217728 }
)

foreach ($Channel in $RoleChannels) {
    if (Test-Path -Path $Channel.Path) {
        Set-ItemProperty -Path $Channel.Path -Name "Retention" -Value 0 -Type DWord -Force
        Set-ItemProperty -Path $Channel.Path -Name "MaxSize" -Value $Channel.MaxSizeBytes -Type DWord -Force
        Write-Host "  [+] Configured $($Channel.Path) MaxSize to $($Channel.MaxSizeBytes) bytes" -ForegroundColor Green
    }
}

Write-Host "[+] Domain Controller Event Log Maximum File Sizes and Retention Policies applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DcEventLogSizesStatus.ps1">Download Script: Get-DcEventLogSizesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-DcEventLogSizesStatus.ps1
# Description: Audits Event Log Maximum File Sizes and Retention Policies on Domain Controllers.

Write-Host "--- Auditing Domain Controller Event Log Maximum File Sizes and Retention Policies ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit Application Log
$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] Application $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Application $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Application $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$ValueName = "MaxSize"
$ExpectedValue = 131072
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ([int64]$Actual -ge [int64]$ExpectedValue) {
            Write-Host "  [+] Application $ValueName = $($Actual) KB (Secure - Meets or exceeds threshold $($ExpectedValue) KB)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Application $ValueName = $($Actual) KB (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Application $ValueName (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 2. Audit Security Log
$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] Security $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Security $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Security $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$ValueName = "MaxSize"
$ExpectedValue = 4194304
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ([int64]$Actual -ge [int64]$ExpectedValue) {
            Write-Host "  [+] Security $ValueName = $($Actual) KB (Secure - Meets or exceeds threshold $($ExpectedValue) KB)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Security $ValueName = $($Actual) KB (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Security $ValueName (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 3. Audit Setup Log
$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] Setup $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Setup $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Setup $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$ValueName = "MaxSize"
$ExpectedValue = 32768
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ([int64]$Actual -ge [int64]$ExpectedValue) {
            Write-Host "  [+] Setup $ValueName = $($Actual) KB (Secure - Meets or exceeds threshold $($ExpectedValue) KB)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Setup $ValueName = $($Actual) KB (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: Setup $ValueName (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 4. Audit System Log
$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] System $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: System $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: System $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$ValueName = "MaxSize"
$ExpectedValue = 262144
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ([int64]$Actual -ge [int64]$ExpectedValue) {
            Write-Host "  [+] System $ValueName = $($Actual) KB (Secure - Meets or exceeds threshold $($ExpectedValue) KB)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: System $ValueName = $($Actual) KB (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: System $ValueName (Expected: &gt;= $($ExpectedValue) KB)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 5. Audit Role-Specific Channels (Directory Service, DNS Server, DFS Replication)
$RoleAudit = @(
    @{ Name = "Directory Service"; Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service"; MinBytes = 268435456 },
    @{ Name = "DNS Server"; Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DNS Server"; MinBytes = 268435456 },
    @{ Name = "DFS Replication"; Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DFS Replication"; MinBytes = 134217728 }
)

foreach ($Item in $RoleAudit) {
    if (Test-Path -Path $Item.Path) {
        $Prop = Get-ItemProperty -Path $Item.Path -ErrorAction SilentlyContinue
        if ($null -ne $Prop) {
            $ActualSize = $Prop.MaxSize
            $ActualRetention = $Prop.Retention
            
            if ($null -ne $ActualRetention -and $ActualRetention -eq 0) {
                Write-Host "  [+] $($Item.Name) Retention = $($ActualRetention) (Secure)" -ForegroundColor Green
            } else {
                Write-Host "  [!] MISMATCH: $($Item.Name) Retention = $($ActualRetention) (Expected: 0)" -ForegroundColor Red
                $script:Vulnerable = $true
            }
            
            if ($null -ne $ActualSize -and [int64]$ActualSize -ge [int64]$Item.MinBytes) {
                Write-Host "  [+] $($Item.Name) MaxSize = $($ActualSize) bytes (Secure - Meets or exceeds threshold $($Item.MinBytes) bytes)" -ForegroundColor Green
            } else {
                Write-Host "  [!] MISMATCH: $($Item.Name) MaxSize = $($ActualSize) bytes (Expected: &gt;= $($Item.MinBytes) bytes)" -ForegroundColor Red
                $script:Vulnerable = $true
            }
        }
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell">#Configure-DcEventLogSizes.ps1
# Description: Configures Event Log Maximum File Sizes and Retention Policies on Domain Controllers.

Write-Host "Configuring Event Log Maximum File Sizes and Retention Policies on Domain Controllers..." -ForegroundColor Cyan

# 1. Core Channels via Policy Registry Branch (values in KB)
if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "MaxSize" -Value 131072 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "MaxSize" -Value 4194304 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "MaxSize" -Value 32768 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "MaxSize" -Value 262144 -Type DWord -Force

# 2. Active Directory Role Channels via Service Registry Branch (values in bytes)
$RoleChannels = @(
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service"; MaxSizeBytes = 268435456 },
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DNS Server"; MaxSizeBytes = 268435456 },
    @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\DFS Replication"; MaxSizeBytes = 134217728 }
)

foreach ($Channel in $RoleChannels) {
    if (Test-Path -Path $Channel.Path) {
        Set-ItemProperty -Path $Channel.Path -Name "Retention" -Value 0 -Type DWord -Force
        Set-ItemProperty -Path $Channel.Path -Name "MaxSize" -Value $Channel.MaxSizeBytes -Type DWord -Force
        Write-Host "  [+] Configured $($Channel.Path) MaxSize to $($Channel.MaxSizeBytes) bytes" -ForegroundColor Green
    }
}

Write-Host "[+] Domain Controller Event Log Maximum File Sizes and Retention Policies applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2160" />
      </check>
    </Rule>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_Defender_Antivirus">
      <title>Defender Antivirus</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-075" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-075] Disable Real-Time Monitoring and Behavior Monitoring Override on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/disable-real-time-monitoring-and-behavior-monitoring-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Real-time scanning, behavior monitoring, and script checking are the core dynamic defense mechanisms of Windows Defender. Disabling or bypassing these controls allows malicious scripts, file-based attacks, and unauthorized in-memory activities to execute undetected.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Turn off real-time protection' to 'Disabled'</xhtml:li>
            <xhtml:li>Set 'Turn on behavior monitoring' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Scan all downloaded files and attachments' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on script scanning' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderRtpDC.ps1">Download Script: Configure-DefenderRtpDC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderRtpDC.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false
$DefenderPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $DefenderPath)) { New-Item -Path $DefenderPath -Force | Out-Null }
Set-ItemProperty -Path $DefenderPath -Name "DisableAntiSpyware" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderRtpDCStatus.ps1">Download Script: Get-DefenderRtpDCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderRtpDCStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableAntiSpyware" -ErrorAction SilentlyContinue
if ($Pref.DisableRealtimeMonitoring -eq $false -and $Pref.DisableBehaviorMonitoring -eq $false -and $Pref.DisableIOAVProtection -eq $false -and $Pref.DisableScriptScanning -eq $false -and ($Reg -and $Reg.DisableAntiSpyware -eq 0)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderRtpDC.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false
$DefenderPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $DefenderPath)) { New-Item -Path $DefenderPath -Force | Out-Null }
Set-ItemProperty -Path $DefenderPath -Name "DisableAntiSpyware" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2075" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-076" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-076] Configure Potentially Unwanted Applications (PUA) Protection on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-potentially-unwanted-applications-pua-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Potentially Unwanted Applications (PUA) include adware, torrent clients, cryptominers, and system optimizers that increase risk and resource consumption. Forcing PUA blocking stops standard vectors of shadow IT and unauthorized utility tool execution.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure detection for potentially unwanted applications' to 'Enabled'</xhtml:li>
            <xhtml:li>Select 'Block' in the options dropdown list</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderPUA.ps1">Download Script: Configure-DefenderPUA.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderPUAStatus.ps1">Download Script: Get-DefenderPUAStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderPUAStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -ErrorAction SilentlyContinue
if ($Pref.PUAProtection -eq 1 -or ($Reg -and $Reg.PUAProtection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2076" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-077" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-077] Prevent Local List Merging and Exclusions Configuration on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/prevent-local-list-merging-and-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>If local administrators or compromised administrative accounts can modify Defender exclusions or merge local lists, they can authorize malicious folders or tools. Restricting list configuration to central GPOs ensures consistent security enforcement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure local administrator merge behavior for lists' to 'Disabled'</xhtml:li>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Prevent users from configuring exclusions' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Control whether or not exclusions are visible to Local Admins' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderLocalExclusions.ps1">Download Script: Configure-DefenderLocalExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderLocalExclusionsStatus.ps1">Download Script: Get-DefenderLocalExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderLocalExclusionsStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableLocalAdminMerge" -ErrorAction SilentlyContinue
$RegHide = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "HideExclusionsFromLocalAdmins" -ErrorAction SilentlyContinue
$RegConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableLocalAdminConfiguration" -ErrorAction SilentlyContinue
if (($Pref.DisableLocalAdminMerge -eq $true -or ($Reg -and $Reg.DisableLocalAdminMerge -eq 1)) -and
    ($RegHide -and $RegHide.HideExclusionsFromLocalAdmins -eq 1) -and
    ($RegConfig -and $RegConfig.DisableLocalAdminConfiguration -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2077" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-078" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-078] Configure Auto Exclusions Configuration on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-auto-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auto Exclusions automatically configure exclusions for known safe system folders or server roles to reduce performance overhead. Enforcing that auto exclusions are not disabled ensures server performance stability and proper system scanning.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Turn off Auto Exclusions' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderAutoExclusions.ps1">Download Script: Configure-DefenderAutoExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderAutoExclusionsStatus.ps1">Download Script: Get-DefenderAutoExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderAutoExclusionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableAutoExclusions" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.DisableAutoExclusions -eq 0) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2078" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-079" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-079] Prevent MAPS Local Setting Override on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/prevent-maps-local-setting-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Preventing local overrides of Microsoft Active Protection Service (MAPS) reporting ensures that Domain Controllers consistently report telemetry and signature feedback to cloud resources, preserving centralized protective visibility.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\MAPS</xhtml:li>
            <xhtml:li>Set 'Join Microsoft MAPS' to 'Disabled' (or prevent override to SpynetReporting = 0)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderSpynetDC.ps1">Download Script: Configure-DefenderSpynetDC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderSpynetDC.ps1
$SpynetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet"
if (-not (Test-Path $SpynetPath)) { New-Item -Path $SpynetPath -Force | Out-Null }
Set-ItemProperty -Path $SpynetPath -Name "SpynetReporting" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderSpynetDCStatus.ps1">Download Script: Get-DefenderSpynetDCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderSpynetDCStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "SpynetReporting" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.SpynetReporting -eq 0) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderSpynetDC.ps1
$SpynetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet"
if (-not (Test-Path $SpynetPath)) { New-Item -Path $SpynetPath -Force | Out-Null }
Set-ItemProperty -Path $SpynetPath -Name "SpynetReporting" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2079" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-080" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-080] Enable EDR in Block Mode on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/enable-edr-in-block-mode.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Endpoint Detection and Response (EDR) in Block Mode allows Defender to take remediation actions on malicious artifacts detected by Microsoft Defender for Endpoint even if another non-Microsoft antivirus is primary. This establishes secondary defensive block capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Features</xhtml:li>
            <xhtml:li>Set 'Enable EDR in block mode' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderEdrBlockMode.ps1">Download Script: Configure-DefenderEdrBlockMode.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderEdrBlockModeStatus.ps1">Download Script: Get-DefenderEdrBlockModeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderEdrBlockModeStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features" -Name "PassiveRemediation" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.PassiveRemediation -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2080" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-081" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-081] Allow Network Protection on Windows Server on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/allow-network-protection-on-windows-server.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Network Protection blocks processes from accessing malicious domains, phishing sites, and host IP ranges. Allowing Network Protection on Windows Server ensures that member servers running server workloads possess the same IP filter protections as client platforms.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Network Protection</xhtml:li>
            <xhtml:li>Set 'This setting controls whether Network Protection is allowed to be configured into block or audit mode on Windows Server' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderNetworkProtectionServer.ps1">Download Script: Configure-DefenderNetworkProtectionServer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderNetworkProtectionServerStatus.ps1">Download Script: Get-DefenderNetworkProtectionServerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderNetworkProtectionServerStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" -Name "AllowNetworkProtectionOnWinServer" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.AllowNetworkProtectionOnWinServer -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2081" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-082" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-082] Enable File Hash Computation on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/enable-file-hash-computation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Computing cryptographic file hashes allows Defender to pass hashes of scanned files to cloud and SIEM Domain Controllers. This enables precise IOC matches, file tracking, and correlation with threat intelligence repositories.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\MpEngine</xhtml:li>
            <xhtml:li>Set 'Enable file hash computation feature' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderFileHash.ps1">Download Script: Configure-DefenderFileHash.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderFileHashStatus.ps1">Download Script: Get-DefenderFileHashStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderFileHashStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" -Name "EnableFileHashComputation" -ErrorAction SilentlyContinue
if ($Pref.EnableFileHashComputation -eq $true -or ($Reg -and $Reg.EnableFileHashComputation -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2082" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-083" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-083] Configure Network Inspection System (NIS) settings on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-network-inspection-system-nis-settings.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Network Inspection System (NIS) inspects network traffic patterns for known exploits. Converting warning verdicts to block enforces inline blocking of zero-day exploits, while allowing async inspection prevents performance overhead from slowing local network interfaces.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Network Inspection System</xhtml:li>
            <xhtml:li>Set 'Convert warn verdict to block' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on asynchronous inspection' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderNis.ps1">Download Script: Configure-DefenderNis.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderNisStatus.ps1">Download Script: Get-DefenderNisStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderNisStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "EnableConvertWarnToBlock" -ErrorAction SilentlyContinue
$RegAsync = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "AllowSwitchToAsyncInspection" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.EnableConvertWarnToBlock -eq 1) -and ($RegAsync -and $RegAsync.AllowSwitchToAsyncInspection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2083" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-084" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-084] Configure OOBE Real-Time Protection and Security Intelligence on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-oobe-real-time-protection-and-security-intelligence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling real-time protection and intelligence updates during the Out-of-Box Experience (OOBE) ensures that the system is fully updated and protected before the initial administrative user signs in or connects to enterprise network nodes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Configure real-time protection and Security Intelligence Updates during OOBE' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderOobeRtp.ps1">Download Script: Configure-DefenderOobeRtp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderOobeRtpStatus.ps1">Download Script: Get-DefenderOobeRtpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderOobeRtpStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "OobeEnableRtpAndSigUpdate" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.OobeEnableRtpAndSigUpdate -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2084" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-085" severity="low" weight="10.0" selected="false">
        <title>[REQ-DC-085] Enable Dynamic Signature Dropped Event Reporting on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/enable-dynamic-signature-dropped-event-reporting.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling this log report generation triggers explicit events when a dynamic scan ruleset signature is dropped. This ensures SIEM integrations can immediately log changes in the local threat signatures dataset.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Reporting</xhtml:li>
            <xhtml:li>Set 'Configure whether to report Dynamic Signature dropped events' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderDynamicReporting.ps1">Download Script: Configure-DefenderDynamicReporting.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderDynamicReportingStatus.ps1">Download Script: Get-DefenderDynamicReportingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderDynamicReportingStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" -Name "EnableDynamicSignatureDroppedEventReporting" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.EnableDynamicSignatureDroppedEventReporting -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2085" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-086" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-086] Configure Quick Scan and Scanning Exclusions on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-quick-scan-and-scanning-exclusions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Malware frequently tries to establish persistence in excluded directories or inside packed/compressed executables. Forcing quick scans to include excluded files and ensuring packed file structures are recursively scanned prevents malware evasion.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Scan excluded files and directories during quick scans' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn off scanning of packed executables' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderQuickScan.ps1">Download Script: Configure-DefenderQuickScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderQuickScanStatus.ps1">Download Script: Get-DefenderQuickScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderQuickScanStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "QuickScanIncludeExclusions" -ErrorAction SilentlyContinue
$RegPack = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DisablePackedExeScanning" -ErrorAction SilentlyContinue
if (($Pref.DisablePackedExeScanning -eq $false -or ($RegPack -and $RegPack.DisablePackedExeScanning -eq 0)) -and
    ($Reg -and $Reg.QuickScanIncludeExclusions -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2086" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-087" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-087] Configure Scheduled Scan Parameters on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-scheduled-scan-parameters.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Ensuring daily scheduled scans, enabling heuristics for behavioral anomaly detection, scan mail attachments, and forcing a catchup scan after at most 7 days ensures system integrity is continually validated.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to run a scheduled scan' to 'Enabled' (Select 'Every day' or '0')</xhtml:li>
            <xhtml:li>Set 'Turn on e-mail scanning' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on heuristics' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Trigger a quick scan after X days without any scans' to 'Enabled' (7 days)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderScheduledScan.ps1">Download Script: Configure-DefenderScheduledScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderScheduledScanStatus.ps1">Download Script: Get-DefenderScheduledScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderScheduledScanStatus.ps1
$Pref = Get-MpPreference
$RegDays = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DaysWithoutCatchupQuickScan" -ErrorAction SilentlyContinue
if ($Pref.DisableEmailScanning -eq $false -and $Pref.DisableHeuristics -eq $false -and ($RegDays -and $RegDays.DaysWithoutCatchupQuickScan -eq 7)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2087" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-088" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-088] Configure Security Intelligence Update Schedule on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-security-intelligence-update-schedule.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Antivirus signatures must remain fresh to block the latest published threats. Mandating daily checks for updates and marking signatures older than 7 days as out-of-date ensures continuous defense parity.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Security Intelligence Updates</xhtml:li>
            <xhtml:li>Set 'Define the number of days before spyware security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Define the number of days before virus security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to check for security intelligence updates' to 'Enabled' (Every day or 0)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderUpdateSchedule.ps1">Download Script: Configure-DefenderUpdateSchedule.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderUpdateScheduleStatus.ps1">Download Script: Get-DefenderUpdateScheduleStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderUpdateScheduleStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ASSignatureDue" -ErrorAction SilentlyContinue
$RegAV = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "AVSignatureDue" -ErrorAction SilentlyContinue
$RegDay = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ScheduleDay" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.ASSignatureDue -eq 7) -and ($RegAV -and $RegAV.AVSignatureDue -eq 7) -and ($RegDay -and $RegDay.ScheduleDay -eq 0)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2088" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-090" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-090] Configure Threat Severity Default Quarantine Actions on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-threat-severity-default-quarantine-actions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>By default, Defender may prompt users or take actions (like clean/ignore) that leave malware remnants on the filesystem. Configuring default quarantine actions for all severities (low, medium, high, severe) ensures automated containment.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Threats</xhtml:li>
            <xhtml:li>Set 'Specify threat alert levels at which default action should not be taken when detected' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and enter threat levels (1 -&gt; 2, 2 -&gt; 2, 4 -&gt; 2, 5 -&gt; 2)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderThreatActions.ps1">Download Script: Configure-DefenderThreatActions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderThreatActionsStatus.ps1">Download Script: Get-DefenderThreatActionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderThreatActionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats" -Name "Threats_ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
$RegSev = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.Threats_ThreatSeverityDefaultAction -eq 1) -and 
    ($RegSev -and $RegSev.1 -eq 2 -and $RegSev.2 -eq 2 -and $RegSev.4 -eq 2 -and $RegSev.5 -eq 2)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2090" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-091" severity="low" weight="10.0" selected="false">
        <title>[REQ-DC-091] Configure Family Options UI Lockdown on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-family-options-ui-lockdown.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Locking down non-essential components of the Windows Security Center interface prevents users from tampering with parental or diagnostic UI controls on enterprise assets.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Family options</xhtml:li>
            <xhtml:li>Set 'Hide the Family options area' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderFamilyLockdown.ps1">Download Script: Configure-DefenderFamilyLockdown.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderFamilyLockdownStatus.ps1">Download Script: Get-DefenderFamilyLockdownStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderFamilyLockdownStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options" -Name "UILockdown" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.UILockdown -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2091" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-092" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-092] Configure Tamper Protection on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-tamper-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Tamper Protection prevents local administrators or compromised system accounts from disabling Windows Defender services, real-time scanning, or modifying active exclusions locally. This blocks a primary malware persistence vector.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Tamper Protection</xhtml:li>
            <xhtml:li>Set 'Protect Windows Security settings from tampering' to 'Enabled' (Block or On depending on ADMX version)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderTamperProtection.ps1">Download Script: Configure-DefenderTamperProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderTamperProtectionStatus.ps1">Download Script: Get-DefenderTamperProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderTamperProtectionStatus.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
$TamperVal = Get-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -ErrorAction SilentlyContinue
if ($TamperVal -and $TamperVal.TamperProtection -eq 5) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2092" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-093" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-093] Configure Sandbox Execution Environment on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-sandbox-execution-environment.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Forcing the Windows Defender scanning service (MsMpEng.exe) to run in a restricted AppContainer sandbox prevents privilege escalation. If an attacker exploits a parsing vulnerability in the engine, the compromise is contained inside the sandbox.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Environment</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Environment Variable</xhtml:li>
            <xhtml:li>Configure Action: Update, Type: System, Name: MP_FORCE_USE_SANDBOX, Value: 1</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderSandbox.ps1">Download Script: Configure-DefenderSandbox.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderSandboxStatus.ps1">Download Script: Get-DefenderSandboxStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderSandboxStatus.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
$SandboxVar = Get-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -ErrorAction SilentlyContinue
if ($SandboxVar -and $SandboxVar.MP_FORCE_USE_SANDBOX -eq "1") {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2093" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-094" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-094] Configure AMSI Authenticode Signature Verification on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-amsi-authenticode-signature-verification.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing signature checks on registered Antimalware Scan Interface (AMSI) providers blocks attackers from registering unsigned rogue AMSI provider DLLs to bypass script analysis.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Registry</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Registry Item</xhtml:li>
            <xhtml:li>Configure Action: Update, Hive: HKEY_LOCAL_MACHINE, Key Path: SOFTWARE\Microsoft\AMSI, Value Name: FeatureBits, Value Type: REG_DWORD, Value Data: 2</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderAmsiSignature.ps1">Download Script: Configure-DefenderAmsiSignature.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderAmsiSignatureStatus.ps1">Download Script: Get-DefenderAmsiSignatureStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderAmsiSignatureStatus.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (Test-Path $AmsiPath) {
    $AmsiBits = Get-ItemProperty -Path $AmsiPath -Name "FeatureBits" -ErrorAction SilentlyContinue
    if ($AmsiBits -and $AmsiBits.FeatureBits -eq 2) {
        Write-Output "Compliant"
        exit 0
    }
}
Write-Output "Non-Compliant"
exit 1</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2094" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-095" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-095] Disable Generic Reports on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/disable-generic-reports.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Disabling generic telemetry and reports on Domain Controllers restricts the transmission of potentially sensitive metadata or environment data regarding Tier 0 directory services to external cloud resources.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Reporting</xhtml:li>
            <xhtml:li>Set 'Configure generic reports' to 'Disabled' (or set DisableGenericRePorts = 1)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderDisableGenericReports.ps1">Download Script: Configure-DefenderDisableGenericReports.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderDisableGenericReports.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableGenericRePorts" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderDisableGenericReportsStatus.ps1">Download Script: Get-DefenderDisableGenericReportsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderDisableGenericReportsStatus.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
$Reg = Get-ItemProperty -Path $Path -Name "DisableGenericRePorts" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.DisableGenericRePorts -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderDisableGenericReports.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableGenericRePorts" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2095" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-096" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-096] Configure Behavioral Network Brute Force Protection Aggressiveness on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-brute-force-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Active Directory Domain Controllers are prime targets for automated password brute-forcing and Kerberos pre-authentication spraying attacks. Setting brute force protection aggressiveness to 1 enables immediate behavioral blocks against network authentication flood sources.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Remediation\Behavioral Network Blocks</xhtml:li>
            <xhtml:li>Set 'Configure behavioral network brute force protection aggressiveness' to 'Enabled' (Select '1')</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderBruteForceProtection.ps1">Download Script: Configure-DefenderBruteForceProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderBruteForceProtection.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "BruteForceProtectionAggressiveness" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderBruteForceProtectionStatus.ps1">Download Script: Get-DefenderBruteForceProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderBruteForceProtectionStatus.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
$Reg = Get-ItemProperty -Path $Path -Name "BruteForceProtectionAggressiveness" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.BruteForceProtectionAggressiveness -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderBruteForceProtection.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "BruteForceProtectionAggressiveness" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2096" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-097" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-097] Configure Behavioral Network Remote Encryption Protection Aggressiveness on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/configure-remote-encryption-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Ransomware groups target SYSVOL and SYSVOL shares on Domain Controllers to deploy encrypted templates or payloads. Enabling remote encryption protection aggressiveness blocks remote network-driven encryption attempts immediately.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Remediation\Behavioral Network Blocks</xhtml:li>
            <xhtml:li>Set 'Configure behavioral network remote encryption protection aggressiveness' to 'Enabled' (Select '1')</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderRemoteEncryptionProtection.ps1">Download Script: Configure-DefenderRemoteEncryptionProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderRemoteEncryptionProtection.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Remote Encryption Protection"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "RemoteEncryptionProtectionAggressiveness" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderRemoteEncryptionProtectionStatus.ps1">Download Script: Get-DefenderRemoteEncryptionProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderRemoteEncryptionProtectionStatus.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Remote Encryption Protection"
$Reg = Get-ItemProperty -Path $Path -Name "RemoteEncryptionProtectionAggressiveness" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.RemoteEncryptionProtectionAggressiveness -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderRemoteEncryptionProtection.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Remote Encryption Protection"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "RemoteEncryptionProtectionAggressiveness" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2097" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_Attack_Surface_Reduction__ASR__Rules">
      <title>Attack Surface Reduction (ASR) Rules</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-098" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-098] ASR: Block abuse of exploited vulnerable signed drivers on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/block-vulnerable-signed-drivers.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents an application from writing a vulnerable signed driver to disk. Attackers use Bring Your Own Vulnerable Driver (BYOVD) techniques to bypass Windows kernel protections by loading legitimate, signed third-party drivers that contain known vulnerabilities, allowing them to disable security agents and gain kernel-level privileges.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>56a863a9-875e-4185-98a7-b882c64b5ce5</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrVulnerableDrivers.ps1">Download Script: Configure-DcAsrVulnerableDrivers.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrVulnerableDriversStatus.ps1">Download Script: Get-DcAsrVulnerableDriversStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrVulnerableDriversStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -ErrorAction SilentlyContinue
if ($Value -and ($Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq "1" -or $Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2098" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-099" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-099] ASR: Block credential stealing from the Windows local security authority subsystem on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/block-lsass-credential-stealing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks attempts to open or dump the memory of the Local Security Authority Subsystem Service (lsass.exe). Attackers dump LSASS memory using tools like Mimikatz or Task Manager to extract plaintext credentials, Kerberos tickets, or NTLM password hashes from system memory for lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrLsassDump.ps1">Download Script: Configure-DcAsrLsassDump.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrLsassDumpStatus.ps1">Download Script: Get-DcAsrLsassDumpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrLsassDumpStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -ErrorAction SilentlyContinue
if ($Value -and ($Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq "1" -or $Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2099" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-100" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-100] ASR: Block execution of potentially obfuscated scripts on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/block-obfuscated-scripts.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks execution of obfuscated or encrypted scripts (such as PowerShell, VBScript, or JavaScript). Threat actors obfuscate their scripts using base64 encoding, custom string manipulation, or encryption to hide the intent of their code and bypass static file scanning and network detection engines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>5beb7efe-fd9a-4556-801d-275e5ffc04cc</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrObfuscatedScripts.ps1">Download Script: Configure-DcAsrObfuscatedScripts.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrObfuscatedScriptsStatus.ps1">Download Script: Get-DcAsrObfuscatedScriptsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrObfuscatedScriptsStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -ErrorAction SilentlyContinue
if ($Value -and ($Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq "1" -or $Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2100" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-101" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-101] ASR: Block persistence through WMI event subscription on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/block-wmi-event-subscription-persistence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks threat actors from achieving system persistence by registering permanent Windows Management Instrumentation (WMI) event subscriptions. WMI event subscriptions allow attackers to automatically launch malicious payloads when system triggers occur (like system boot or user logon) without using traditional startup registry keys.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>e6db77e5-3df2-4cf1-b95a-636979351e5b</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrWmiPersistence.ps1">Download Script: Configure-DcAsrWmiPersistence.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrWmiPersistenceStatus.ps1">Download Script: Get-DcAsrWmiPersistenceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrWmiPersistenceStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -ErrorAction SilentlyContinue
if ($Value -and ($Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq "1" -or $Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2101" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-102" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-102] ASR: Block process creations originating from PSExec and WMI commands on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/block-psexec-wmi-process-creations.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks processes created via WMI commands or PSExec remote execution utilities. This directly stops lateral movement attacks where compromised accounts or threat actors attempt to start commands, backdoors, or credential dumpers remotely across domain-joined servers and Domain Controllers.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d1e49aac-8f56-4280-b9ba-993a6d77406c</xhtml:code> as Value Name, with Value set to <xhtml:code>2</xhtml:code> (Audit).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrPsexecWmi.ps1">Download Script: Configure-DcAsrPsexecWmi.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "2" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrPsexecWmiStatus.ps1">Download Script: Get-DcAsrPsexecWmiStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrPsexecWmiStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq "2" -or $Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq 2)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "2" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2102" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-103" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-103] ASR: Use advanced protection against ransomware on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/defender/asr/use-advanced-protection-against-ransomware.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enables advanced behavioral heuristics and cloud analytics checks on files that attempt to modify multiple user files, detect signature-less encryption behavior, and block rapid write activity to prevent ransomware from encrypting system and user documents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>c1db55ab-c21a-4637-bb3f-a12568109d35</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-DcAsrRansomware.ps1">Download Script: Configure-DcAsrRansomware.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-DcAsrRansomwareStatus.ps1">Download Script: Get-DcAsrRansomwareStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAsrRansomwareStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -ErrorAction SilentlyContinue
if ($Value -and ($Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq "1" -or $Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2103" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_User_Rights_Assignments">
      <title>User Rights Assignments</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-104" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-104] Configure User Rights: Access this computer from the network on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-093](../../07-paws/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-097](../../08-endpoints/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-senetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeNetworkLogonRight</xhtml:code> determines which security principals are permitted to authenticate and establish network logon sessions (Logon Type 3) across the network over protocols like SMB, RPC, WMI, WinRM, and LDAP. Network logons authenticate users without creating an interactive desktop shell, enabling file share access, remote management, and inter-system synchronization.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Access this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-9 (Enterprise Domain Controllers), *S-1-5-11 (Authenticated Users), *S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeNetworkLogonRight.ps1">Download Script: Configure-DcUraSeNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeNetworkLogonRight.ps1
# Configure-DcUraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeNetworkLogonRightStatus.ps1">Download Script: Get-DcUraSeNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeNetworkLogonRightStatus.ps1
# Get-DcUraSeNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_senetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-9,*S-1-5-11,*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeNetworkLogonRight.ps1
# Configure-DcUraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-9,*S-1-5-11,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2104" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-105" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-105] Configure User Rights: Act as part of the operating system on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-094](../../07-paws/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-098](../../08-endpoints/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-setcbprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTcbPrivilege</xhtml:code> identifies its holder as part of the Trusted Computer Base (TCB)—the core inner ring of the operating system. A process possessing this privilege can register as a trusted logon process with the Local Security Authority via <xhtml:code>LsaRegisterLogonProcess</xhtml:code> and invoke <xhtml:code>LsaLogonUser</xhtml:code> to create an arbitrary, fully authenticated access token for any user without knowing the user's password or requiring credentials.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Act as part of the operating system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeTcbPrivilege.ps1">Download Script: Configure-DcUraSeTcbPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeTcbPrivilege.ps1
# Configure-DcUraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeTcbPrivilegeStatus.ps1">Download Script: Get-DcUraSeTcbPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeTcbPrivilegeStatus.ps1
# Get-DcUraSeTcbPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setcbprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTcbPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeTcbPrivilege.ps1
# Configure-DcUraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2105" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-106" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-106] Configure User Rights: Add workstations to domain on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-semachineaccountprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeMachineAccountPrivilege</xhtml:code> allows an authenticated domain user to join computer accounts to the Active Directory domain, creating new computer objects in the default <xhtml:code>CN=Computers</xhtml:code> container up to the limit defined by <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> (default: 10). This privilege is governed by the Domain Controllers policy and domain-level schema.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Add workstations to domain`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeMachineAccountPrivilege.ps1">Download Script: Configure-DcUraSeMachineAccountPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeMachineAccountPrivilege.ps1
# Configure-DcUraSeMachineAccountPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semachineaccountprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semachineaccountprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeMachineAccountPrivilege\s*=") {
        $NewLines += "SeMachineAccountPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeMachineAccountPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeMachineAccountPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeMachineAccountPrivilegeStatus.ps1">Download Script: Get-DcUraSeMachineAccountPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeMachineAccountPrivilegeStatus.ps1
# Get-DcUraSeMachineAccountPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_semachineaccountprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeMachineAccountPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeMachineAccountPrivilege.ps1
# Configure-DcUraSeMachineAccountPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semachineaccountprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semachineaccountprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeMachineAccountPrivilege\s*=") {
        $NewLines += "SeMachineAccountPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeMachineAccountPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeMachineAccountPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2106" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-107" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-107] Configure User Rights: Adjust memory quotas for a process on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seincreasequotaprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeIncreaseQuotaPrivilege</xhtml:code> grants a process the capability to increase the maximum memory quota (working set size and page pool limits) allocated to a process via <xhtml:code>SetProcessWorkingSetSize</xhtml:code> or <xhtml:code>NtSetInformationProcess</xhtml:code>. The memory manager enforces memory quotas to prevent individual processes from monopolizing system memory pools.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Adjust memory quotas for a process`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService), *S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeIncreaseQuotaPrivilege.ps1">Download Script: Configure-DcUraSeIncreaseQuotaPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeIncreaseQuotaPrivilege.ps1
# Configure-DcUraSeIncreaseQuotaPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seincreasequotaprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seincreasequotaprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeIncreaseQuotaPrivilege\s*=") {
        $NewLines += "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544")
    } else {
        $NewLines += "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeIncreaseQuotaPrivilegeStatus.ps1">Download Script: Get-DcUraSeIncreaseQuotaPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeIncreaseQuotaPrivilegeStatus.ps1
# Get-DcUraSeIncreaseQuotaPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seincreasequotaprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeIncreaseQuotaPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20,*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeIncreaseQuotaPrivilege.ps1
# Configure-DcUraSeIncreaseQuotaPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seincreasequotaprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seincreasequotaprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeIncreaseQuotaPrivilege\s*=") {
        $NewLines += "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544")
    } else {
        $NewLines += "SeIncreaseQuotaPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2107" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-108" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-108] Configure User Rights: Allow log on locally on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-095](../../07-paws/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-099](../../08-endpoints/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeInteractiveLogonRight</xhtml:code> determines which security principals are permitted to start an interactive logon session (Logon Type 2) at the physical keyboard, display, or virtual machine console. An interactive logon spawns a graphical user shell (<xhtml:code>explorer.exe</xhtml:code>) and interactive desktop session.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Allow log on locally`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-9 (Enterprise Domain Controllers), *S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeInteractiveLogonRight.ps1">Download Script: Configure-DcUraSeInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeInteractiveLogonRight.ps1
# Configure-DcUraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeInteractiveLogonRightStatus.ps1">Download Script: Get-DcUraSeInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeInteractiveLogonRightStatus.ps1
# Get-DcUraSeInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-9,*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeInteractiveLogonRight.ps1
# Configure-DcUraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2108" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-109" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-109] Configure User Rights: Allow log on through Remote Desktop Services on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seremoteinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRemoteInteractiveLogonRight</xhtml:code> determines which security principals are permitted to establish interactive Remote Desktop Protocol (RDP) sessions (Logon Type 10) on the target host. RDP provides full remote graphical desktop access, loading interactive user credentials into LSASS memory.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Allow log on through Remote Desktop Services`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeRemoteInteractiveLogonRight.ps1">Download Script: Configure-DcUraSeRemoteInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeRemoteInteractiveLogonRight.ps1
# Configure-DcUraSeRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeRemoteInteractiveLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteInteractiveLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteInteractiveLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeRemoteInteractiveLogonRightStatus.ps1">Download Script: Get-DcUraSeRemoteInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeRemoteInteractiveLogonRightStatus.ps1
# Get-DcUraSeRemoteInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seremoteinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRemoteInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeRemoteInteractiveLogonRight.ps1
# Configure-DcUraSeRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeRemoteInteractiveLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteInteractiveLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteInteractiveLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2109" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-110" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-110] Configure User Rights: Back up files and directories on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-096](../../07-paws/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-100](../../08-endpoints/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sebackupprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeBackupPrivilege</xhtml:code> grants the caller the capability to bypass all read-access security controls (Discretionary Access Control Lists - DACLs) across the entire NTFS filesystem and Windows Registry. When an application opens a file handle specifying the <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> flag in Win32 <xhtml:code>CreateFile</xhtml:code> calls, the Windows kernel I/O manager and Object Manager explicitly bypass standard security descriptor evaluation. This design allows legitimate backup utilities to archive files without requiring explicit read permissions on every individual object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Back up files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeBackupPrivilege.ps1">Download Script: Configure-DcUraSeBackupPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeBackupPrivilege.ps1
# Configure-DcUraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeBackupPrivilegeStatus.ps1">Download Script: Get-DcUraSeBackupPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeBackupPrivilegeStatus.ps1
# Get-DcUraSeBackupPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sebackupprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeBackupPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeBackupPrivilege.ps1
# Configure-DcUraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2110" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-111" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-111] Configure User Rights: Bypass traverse checking on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sechangenotifyprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeChangeNotifyPrivilege</xhtml:code> grants the caller the ability to traverse directory trees to access child objects (files and subdirectories) even if the user lacks explicit 'Traverse Folder / Execute File' permissions on parent directories in the path. In addition, this privilege enables applications to register for file system change notifications via APIs such as <xhtml:code>ReadDirectoryChangesW</xhtml:code>. While enabled broadly on workstations for user convenience, on Domain Controllers and hardened infrastructure, directory navigation paths must be securely bounded.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Bypass traverse checking`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-554 (Pre-Windows 2000 Compatible Access), *S-1-5-11 (Authenticated Users), *S-1-5-32-544 (Administrators), *S-1-5-20 (NetworkService), *S-1-5-19 (LocalService), *S-1-1-0 (Everyone)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeChangeNotifyPrivilege.ps1">Download Script: Configure-DcUraSeChangeNotifyPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeChangeNotifyPrivilege.ps1
# Configure-DcUraSeChangeNotifyPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sechangenotifyprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sechangenotifyprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeChangeNotifyPrivilege\s*=") {
        $NewLines += "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0")
    } else {
        $NewLines += "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeChangeNotifyPrivilegeStatus.ps1">Download Script: Get-DcUraSeChangeNotifyPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeChangeNotifyPrivilegeStatus.ps1
# Get-DcUraSeChangeNotifyPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sechangenotifyprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeChangeNotifyPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeChangeNotifyPrivilege.ps1
# Configure-DcUraSeChangeNotifyPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sechangenotifyprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sechangenotifyprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeChangeNotifyPrivilege\s*=") {
        $NewLines += "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0")
    } else {
        $NewLines += "SeChangeNotifyPrivilege = *S-1-5-32-554,*S-1-5-11,*S-1-5-32-544,*S-1-5-20,*S-1-5-19,*S-1-1-0"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2111" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-112" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-112] Configure User Rights: Change the system time on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-101](../../08-endpoints/user-rights/configure-ura-sesystemtimeprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sesystemtimeprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemtimePrivilege</xhtml:code> allows a security principal to adjust the internal hardware clock and system time of the computer via Win32 APIs <xhtml:code>SetSystemTime</xhtml:code> or <xhtml:code>SetLocalTime</xhtml:code>. Accurate time synchronization is foundational to the Windows distributed security architecture.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Change the system time`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-19 (LocalService)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeSystemtimePrivilege.ps1">Download Script: Configure-DcUraSeSystemtimePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeSystemtimePrivilege.ps1
# Configure-DcUraSeSystemtimePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemtimeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemtimeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemtimePrivilege\s*=") {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19")
    } else {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeSystemtimePrivilegeStatus.ps1">Download Script: Get-DcUraSeSystemtimePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeSystemtimePrivilegeStatus.ps1
# Get-DcUraSeSystemtimePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemtimeprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemtimePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-19"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeSystemtimePrivilege.ps1
# Configure-DcUraSeSystemtimePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemtimeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemtimeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemtimePrivilege\s*=") {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19")
    } else {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2112" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-113" severity="low" weight="10.0" selected="false">
        <title>[REQ-DC-113] Configure User Rights: Create a pagefile on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-097](../../07-paws/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-103](../../08-endpoints/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-secreatepagefileprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePagefilePrivilege</xhtml:code> allows a process to create, delete, and modify the parameters and allocation sizes of system paging files (<xhtml:code>pagefile.sys</xhtml:code>) via the <xhtml:code>NtCreatePagingFile</xhtml:code> API. The Windows virtual memory manager uses paging files as secondary backing storage for memory pages that are not backed by files. Paging files contain sensitive plaintext data, including process heap allocations, cached authentication tokens, cryptographic keys, and unencrypted file contents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a pagefile`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeCreatePagefilePrivilege.ps1">Download Script: Configure-DcUraSeCreatePagefilePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeCreatePagefilePrivilege.ps1
# Configure-DcUraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeCreatePagefilePrivilegeStatus.ps1">Download Script: Get-DcUraSeCreatePagefilePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeCreatePagefilePrivilegeStatus.ps1
# Get-DcUraSeCreatePagefilePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepagefileprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePagefilePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeCreatePagefilePrivilege.ps1
# Configure-DcUraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2113" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-114" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-114] Configure User Rights: Create a token object on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-098](../../07-paws/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-104](../../08-endpoints/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-secreatetokenprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateTokenPrivilege</xhtml:code> allows a process to invoke the native API <xhtml:code>NtCreateToken</xhtml:code> to forge an arbitrary Windows primary or impersonation access token from scratch. An access token defines an entity's complete security context, including User SID, Group SIDs, Privileges, Default DACL, Token Type, and Mandatory Integrity Level. Normally, tokens are manufactured exclusively by the Local Security Authority Subsystem Service (<xhtml:code>lsass.exe</xhtml:code>) following successful authentication.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a token object`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeCreateTokenPrivilege.ps1">Download Script: Configure-DcUraSeCreateTokenPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeCreateTokenPrivilege.ps1
# Configure-DcUraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeCreateTokenPrivilegeStatus.ps1">Download Script: Get-DcUraSeCreateTokenPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeCreateTokenPrivilegeStatus.ps1
# Get-DcUraSeCreateTokenPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatetokenprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateTokenPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeCreateTokenPrivilege.ps1
# Configure-DcUraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2114" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-115" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-115] Configure User Rights: Create permanent shared objects on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-100](../../07-paws/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-106](../../08-endpoints/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-secreatepermanentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePermanentPrivilege</xhtml:code> allows a process to create permanent object directory objects in the Windows Object Manager namespace (<xhtml:code>\DirectoryObject</xhtml:code>) via APIs like <xhtml:code>NtCreateDirectoryObject</xhtml:code>. Unlike standard kernel objects which are automatically destroyed when their last handle is closed, permanent objects persist in the object manager namespace across process terminations until explicitly unlinked or until system reboot.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create permanent shared objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeCreatePermanentPrivilege.ps1">Download Script: Configure-DcUraSeCreatePermanentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeCreatePermanentPrivilege.ps1
# Configure-DcUraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeCreatePermanentPrivilegeStatus.ps1">Download Script: Get-DcUraSeCreatePermanentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeCreatePermanentPrivilegeStatus.ps1
# Get-DcUraSeCreatePermanentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepermanentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePermanentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeCreatePermanentPrivilege.ps1
# Configure-DcUraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2115" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-116" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-116] Configure User Rights: Debug programs on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-101](../../07-paws/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-108](../../08-endpoints/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedebugprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDebugPrivilege</xhtml:code> allows a process to attach a debugger to any running process on the system, completely overriding the target process security descriptor and Discretionary Access Control List (DACL). When enabled, calls to <xhtml:code>OpenProcess</xhtml:code> with permissions such as <xhtml:code>PROCESS_ALL_ACCESS</xhtml:code> or <xhtml:code>PROCESS_VM_READ</xhtml:code> succeed even against processes owned by other users or <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>. This privilege is intended strictly for kernel/application developers debugging live processes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Debug programs`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDebugPrivilege.ps1">Download Script: Configure-DcUraSeDebugPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDebugPrivilege.ps1
# Configure-DcUraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDebugPrivilegeStatus.ps1">Download Script: Get-DcUraSeDebugPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDebugPrivilegeStatus.ps1
# Get-DcUraSeDebugPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedebugprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDebugPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDebugPrivilege.ps1
# Configure-DcUraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2116" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-117" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-117] Configure User Rights: Deny access to this computer from the network on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-113](../../07-paws/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-124](../../08-endpoints/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedenynetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyNetworkLogonRight</xhtml:code> explicitly prevents specified security principals from authenticating over network protocols (SMB, RPC, WMI, WinRM, LDAP, etc. - Logon Type 3). Network logons represent the primary highway for lateral movement and remote compromise in Active Directory environments. Enforcing an explicit deny stops network authentication regardless of share-level or NTFS-level permissions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny access to this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-546 (Guests)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDenyNetworkLogonRight.ps1">Download Script: Configure-DcUraSeDenyNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDenyNetworkLogonRight.ps1
# Configure-DcUraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDenyNetworkLogonRightStatus.ps1">Download Script: Get-DcUraSeDenyNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDenyNetworkLogonRightStatus.ps1
# Get-DcUraSeDenyNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenynetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-546"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDenyNetworkLogonRight.ps1
# Configure-DcUraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2117" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-118" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-118] Configure User Rights: Deny log on as a batch job on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedenybatchlogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyBatchLogonRight</xhtml:code> explicitly denies designated security principals the ability to authenticate and run batch or scheduled workloads (Logon Type 4). In Windows security, an explicit 'Deny' right takes precedence over any conflicting 'Allow' right (<xhtml:code>SeBatchLogonRight</xhtml:code>), ensuring that restricted accounts cannot be granted batch execution through nested group memberships.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on as a batch job`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-546 (Guests)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDenyBatchLogonRight.ps1">Download Script: Configure-DcUraSeDenyBatchLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDenyBatchLogonRight.ps1
# Configure-DcUraSeDenyBatchLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenybatchlogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenybatchlogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyBatchLogonRight\s*=") {
        $NewLines += "SeDenyBatchLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyBatchLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyBatchLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDenyBatchLogonRightStatus.ps1">Download Script: Get-DcUraSeDenyBatchLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDenyBatchLogonRightStatus.ps1
# Get-DcUraSeDenyBatchLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenybatchlogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyBatchLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-546"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDenyBatchLogonRight.ps1
# Configure-DcUraSeDenyBatchLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenybatchlogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenybatchlogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyBatchLogonRight\s*=") {
        $NewLines += "SeDenyBatchLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyBatchLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyBatchLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2118" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-119" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-119] Configure User Rights: Deny log on as a service on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedenyservicelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyServiceLogonRight</xhtml:code> explicitly prevents designated accounts from registering and executing as a Windows service process (Logon Type 5). Windows services run unattended in the background under designated security contexts, typically with persistent execution privileges across reboots.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on as a service`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-546 (Guests)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDenyServiceLogonRight.ps1">Download Script: Configure-DcUraSeDenyServiceLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDenyServiceLogonRight.ps1
# Configure-DcUraSeDenyServiceLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyservicelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyservicelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyServiceLogonRight\s*=") {
        $NewLines += "SeDenyServiceLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyServiceLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyServiceLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDenyServiceLogonRightStatus.ps1">Download Script: Get-DcUraSeDenyServiceLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDenyServiceLogonRightStatus.ps1
# Get-DcUraSeDenyServiceLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenyservicelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyServiceLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-546"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDenyServiceLogonRight.ps1
# Configure-DcUraSeDenyServiceLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyservicelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyservicelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyServiceLogonRight\s*=") {
        $NewLines += "SeDenyServiceLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyServiceLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyServiceLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2119" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-120" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-120] Configure User Rights: Deny log on locally on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedenyinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyInteractiveLogonRight</xhtml:code> explicitly blocks designated accounts and groups from establishing an interactive logon session (Logon Type 2) at the physical keyboard, mouse, or virtual machine console. Because an explicit deny overrides any allow right, this policy establishes a foolproof security boundary against unauthorized console access.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on locally`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-546 (Guests)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDenyInteractiveLogonRight.ps1">Download Script: Configure-DcUraSeDenyInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDenyInteractiveLogonRight.ps1
# Configure-DcUraSeDenyInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyInteractiveLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyInteractiveLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyInteractiveLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDenyInteractiveLogonRightStatus.ps1">Download Script: Get-DcUraSeDenyInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDenyInteractiveLogonRightStatus.ps1
# Get-DcUraSeDenyInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenyinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-546"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDenyInteractiveLogonRight.ps1
# Configure-DcUraSeDenyInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyInteractiveLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyInteractiveLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyInteractiveLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2120" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-121" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-121] Configure User Rights: Deny log on through Remote Desktop Services on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-114](../../07-paws/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-125](../../08-endpoints/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sedenyremoteinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyRemoteInteractiveLogonRight</xhtml:code> explicitly denies designated accounts the ability to establish Remote Desktop Protocol (RDP) sessions (Logon Type 10) on the target system. RDP exposes a full graphical interactive session over TCP port 3389, providing an attacker with interactive desktop capabilities and loading user credentials into memory.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on through Remote Desktop Services`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-546 (Guests)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1">Download Script: Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1
# Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeDenyRemoteInteractiveLogonRightStatus.ps1">Download Script: Get-DcUraSeDenyRemoteInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeDenyRemoteInteractiveLogonRightStatus.ps1
# Get-DcUraSeDenyRemoteInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenyremoteinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyRemoteInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-546"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1
# Configure-DcUraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-32-546"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2121" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-122" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-122] Configure User Rights: Enable computer and user accounts to be trusted for delegation on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-102](../../07-paws/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-109](../../08-endpoints/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seenabledelegationprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeEnableDelegationPrivilege</xhtml:code> allows a security principal to modify the <xhtml:code>userAccountControl</xhtml:code> attribute on Active Directory user and computer objects to enable Kerberos Delegation flags: (1) <xhtml:code>TRUSTED_FOR_DELEGATION</xhtml:code> (Unconstrained Delegation); (2) <xhtml:code>TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION</xhtml:code> (Constrained Delegation with Protocol Transition / S4U2Self). Kerberos delegation permits a service to impersonate an authenticated user to access back-end resources on their behalf.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Enable computer and user accounts to be trusted for delegation`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeEnableDelegationPrivilege.ps1">Download Script: Configure-DcUraSeEnableDelegationPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeEnableDelegationPrivilege.ps1
# Configure-DcUraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeEnableDelegationPrivilegeStatus.ps1">Download Script: Get-DcUraSeEnableDelegationPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeEnableDelegationPrivilegeStatus.ps1
# Get-DcUraSeEnableDelegationPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seenabledelegationprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeEnableDelegationPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeEnableDelegationPrivilege.ps1
# Configure-DcUraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2122" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-123" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-123] Configure User Rights: Force shutdown from a remote system on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-103](../../07-paws/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-110](../../08-endpoints/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seremoteshutdownprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRemoteShutdownPrivilege</xhtml:code> allows a user authenticating over the network to invoke remote system shutdown and reboot APIs (such as <xhtml:code>InitiateSystemShutdownEx</xhtml:code> or <xhtml:code>shutdown.exe /m \\computer</xhtml:code>). This function is exposed over named pipe <xhtml:code>\PIPE\InitShutdown</xhtml:code> and RPC interface <xhtml:code>winreg</xhtml:code>/<xhtml:code>shutdown</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Force shutdown from a remote system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeRemoteShutdownPrivilege.ps1">Download Script: Configure-DcUraSeRemoteShutdownPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeRemoteShutdownPrivilege.ps1
# Configure-DcUraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeRemoteShutdownPrivilegeStatus.ps1">Download Script: Get-DcUraSeRemoteShutdownPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeRemoteShutdownPrivilegeStatus.ps1
# Get-DcUraSeRemoteShutdownPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seremoteshutdownprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRemoteShutdownPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeRemoteShutdownPrivilege.ps1
# Configure-DcUraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2123" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-124" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-124] Configure User Rights: Generate security audits on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seauditprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeAuditPrivilege</xhtml:code> allows a process to write synthetic records directly into the Windows Security Event Log (<xhtml:code>Security.evtx</xhtml:code>) by invoking the Local Security Authority (LSA) and Authz APIs, specifically <xhtml:code>AuthzReportSecurityEvent</xhtml:code> or <xhtml:code>LsaRegisterLogonProcess</xhtml:code>. The Windows Security event log is the primary tamper-resistant telemetry source for forensic investigations, compliance audits, and Security Information and Event Management (SIEM) ingest. Access to inject events directly into this log without generating standard OS audit trails represents a critical security hazard.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Generate security audits`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeAuditPrivilege.ps1">Download Script: Configure-DcUraSeAuditPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeAuditPrivilege.ps1
# Configure-DcUraSeAuditPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seauditprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seauditprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeAuditPrivilege\s*=") {
        $NewLines += "SeAuditPrivilege = *S-1-5-19,*S-1-5-20"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeAuditPrivilege = *S-1-5-19,*S-1-5-20")
    } else {
        $NewLines += "SeAuditPrivilege = *S-1-5-19,*S-1-5-20"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeAuditPrivilegeStatus.ps1">Download Script: Get-DcUraSeAuditPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeAuditPrivilegeStatus.ps1
# Get-DcUraSeAuditPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seauditprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeAuditPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeAuditPrivilege.ps1
# Configure-DcUraSeAuditPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seauditprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seauditprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeAuditPrivilege\s*=") {
        $NewLines += "SeAuditPrivilege = *S-1-5-19,*S-1-5-20"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeAuditPrivilege = *S-1-5-19,*S-1-5-20")
    } else {
        $NewLines += "SeAuditPrivilege = *S-1-5-19,*S-1-5-20"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2124" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-125" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-125] Configure User Rights: Load and unload device drivers on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-105](../../07-paws/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-113](../../08-endpoints/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seloaddriverprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLoadDriverPrivilege</xhtml:code> allows a process to dynamically load and unload kernel-mode device drivers (<xhtml:code>.sys</xhtml:code> files) via <xhtml:code>NtLoadDriver</xhtml:code> or the Service Control Manager (<xhtml:code>CreateService</xhtml:code> with <xhtml:code>SERVICE_KERNEL_DRIVER</xhtml:code>). Kernel-mode drivers execute in Ring 0 with unrestricted hardware access, full kernel memory read/write permissions, and the ability to execute any CPU instruction.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Load and unload device drivers`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeLoadDriverPrivilege.ps1">Download Script: Configure-DcUraSeLoadDriverPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeLoadDriverPrivilege.ps1
# Configure-DcUraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeLoadDriverPrivilegeStatus.ps1">Download Script: Get-DcUraSeLoadDriverPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeLoadDriverPrivilegeStatus.ps1
# Get-DcUraSeLoadDriverPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seloaddriverprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLoadDriverPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeLoadDriverPrivilege.ps1
# Configure-DcUraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2125" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-126" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-126] Configure User Rights: Lock pages in memory on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-106](../../07-paws/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-114](../../08-endpoints/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-selockmemoryprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLockMemoryPrivilege</xhtml:code> allows a process to lock physical memory pages in RAM using APIs such as <xhtml:code>VirtualLock</xhtml:code> and Address Windowing Extensions (AWE) via <xhtml:code>AllocateUserPhysicalPages</xhtml:code>. Locking pages prevents the Windows virtual memory manager from paging data out to disk in <xhtml:code>pagefile.sys</xhtml:code>, ensuring high-performance memory retention.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Lock pages in memory`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeLockMemoryPrivilege.ps1">Download Script: Configure-DcUraSeLockMemoryPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeLockMemoryPrivilege.ps1
# Configure-DcUraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeLockMemoryPrivilegeStatus.ps1">Download Script: Get-DcUraSeLockMemoryPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeLockMemoryPrivilegeStatus.ps1
# Get-DcUraSeLockMemoryPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_selockmemoryprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLockMemoryPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeLockMemoryPrivilege.ps1
# Configure-DcUraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2126" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-127" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-127] Configure User Rights: Log on as a batch job on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sebatchlogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeBatchLogonRight</xhtml:code> determines which security principals can authenticate and establish non-interactive batch logon sessions (Logon Type 4). Batch logons are utilized by the Task Scheduler (<xhtml:code>taskschd.msc</xhtml:code>) and batch queuing subsystems to execute scheduled tasks, maintenance scripts, and background workloads without requiring an interactive desktop session or terminal connection.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Log on as a batch job`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeBatchLogonRight.ps1">Download Script: Configure-DcUraSeBatchLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeBatchLogonRight.ps1
# Configure-DcUraSeBatchLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebatchlogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebatchlogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBatchLogonRight\s*=") {
        $NewLines += "SeBatchLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBatchLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeBatchLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeBatchLogonRightStatus.ps1">Download Script: Get-DcUraSeBatchLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeBatchLogonRightStatus.ps1
# Get-DcUraSeBatchLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sebatchlogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeBatchLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeBatchLogonRight.ps1
# Configure-DcUraSeBatchLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebatchlogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebatchlogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBatchLogonRight\s*=") {
        $NewLines += "SeBatchLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBatchLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeBatchLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2127" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-128" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-128] Configure User Rights: Log on as a service on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seservicelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeServiceLogonRight</xhtml:code> determines which security principals are permitted to register and authenticate as background Windows service accounts (Logon Type 5). When the Service Control Manager (<xhtml:code>services.exe</xhtml:code>) starts a service configured with a user account, it initiates a service logon session.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Log on as a service`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeServiceLogonRight.ps1">Download Script: Configure-DcUraSeServiceLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeServiceLogonRight.ps1
# Configure-DcUraSeServiceLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seservicelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seservicelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeServiceLogonRight\s*=") {
        $NewLines += "SeServiceLogonRight = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeServiceLogonRight = ")
    } else {
        $NewLines += "SeServiceLogonRight = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeServiceLogonRightStatus.ps1">Download Script: Get-DcUraSeServiceLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeServiceLogonRightStatus.ps1
# Get-DcUraSeServiceLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seservicelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeServiceLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeServiceLogonRight.ps1
# Configure-DcUraSeServiceLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seservicelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seservicelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeServiceLogonRight\s*=") {
        $NewLines += "SeServiceLogonRight = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeServiceLogonRight = ")
    } else {
        $NewLines += "SeServiceLogonRight = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2128" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-129" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-129] Configure User Rights: Manage auditing and security log on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-107](../../07-paws/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-115](../../08-endpoints/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sesecurityprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSecurityPrivilege</xhtml:code> controls access to the Windows Security Event Log (<xhtml:code>Security.evtx</xhtml:code>) and governs the ability to view, configure, and clear the security log, as well as specify object auditing options (System Access Control Lists - SACLs) on files, registry keys, and directory objects via <xhtml:code>ACCESS_SYSTEM_SECURITY</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Manage auditing and security log`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeSecurityPrivilege.ps1">Download Script: Configure-DcUraSeSecurityPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeSecurityPrivilege.ps1
# Configure-DcUraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeSecurityPrivilegeStatus.ps1">Download Script: Get-DcUraSeSecurityPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeSecurityPrivilegeStatus.ps1
# Get-DcUraSeSecurityPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesecurityprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSecurityPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeSecurityPrivilege.ps1
# Configure-DcUraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2129" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-130" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-130] Configure User Rights: Modify firmware environment values on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-108](../../07-paws/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-116](../../08-endpoints/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sesystemenvironmentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemEnvironmentPrivilege</xhtml:code> allows a process to query and modify Non-Volatile RAM (NVRAM) firmware environment variables via Win32 APIs <xhtml:code>GetFirmwareEnvironmentVariable</xhtml:code> and <xhtml:code>SetFirmwareEnvironmentVariable</xhtml:code>. NVRAM variables govern UEFI boot sequences, Secure Boot policies, boot configuration data (BCD) handoffs, and hardware configuration flags.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Modify firmware environment values`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeSystemEnvironmentPrivilege.ps1">Download Script: Configure-DcUraSeSystemEnvironmentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeSystemEnvironmentPrivilege.ps1
# Configure-DcUraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeSystemEnvironmentPrivilegeStatus.ps1">Download Script: Get-DcUraSeSystemEnvironmentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeSystemEnvironmentPrivilegeStatus.ps1
# Get-DcUraSeSystemEnvironmentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemenvironmentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemEnvironmentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeSystemEnvironmentPrivilege.ps1
# Configure-DcUraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2130" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-131" severity="low" weight="10.0" selected="false">
        <title>[REQ-DC-131] Configure User Rights: Profile single process on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-110](../../07-paws/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-118](../../08-endpoints/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seprofilesingleprocessprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeProfileSingleProcessPrivilege</xhtml:code> allows a process to monitor and profile the performance and execution metrics of non-system processes using Windows performance sampling APIs. Profiling tools monitor instruction execution rates, thread context switches, memory cache behavior, and execution sampling.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Profile single process`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeProfileSingleProcessPrivilege.ps1">Download Script: Configure-DcUraSeProfileSingleProcessPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeProfileSingleProcessPrivilege.ps1
# Configure-DcUraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeProfileSingleProcessPrivilegeStatus.ps1">Download Script: Get-DcUraSeProfileSingleProcessPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeProfileSingleProcessPrivilegeStatus.ps1
# Get-DcUraSeProfileSingleProcessPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seprofilesingleprocessprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeProfileSingleProcessPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeProfileSingleProcessPrivilege.ps1
# Configure-DcUraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2131" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-132" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-132] Configure User Rights: Restore files and directories on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-111](../../07-paws/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-121](../../08-endpoints/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-serestoreprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRestorePrivilege</xhtml:code> grants the caller the capability to bypass all write-access security controls (DACLs) across the entire NTFS filesystem and Windows Registry. When a process opens a file or registry key handle specifying <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> in Win32 APIs, the kernel explicitly bypasses standard security descriptor DACL checks, allowing the process to write to, overwrite, or delete any file or key on the system. In addition, this privilege grants the ability to set any valid user or group SID as the owner of an object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Restore files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeRestorePrivilege.ps1">Download Script: Configure-DcUraSeRestorePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeRestorePrivilege.ps1
# Configure-DcUraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeRestorePrivilegeStatus.ps1">Download Script: Get-DcUraSeRestorePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeRestorePrivilegeStatus.ps1
# Get-DcUraSeRestorePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_serestoreprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRestorePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeRestorePrivilege.ps1
# Configure-DcUraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2132" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-133" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-133] Configure User Rights: Shut down the system on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-seshutdownprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeShutdownPrivilege</xhtml:code> controls the capability of a user logged on locally at the console to cleanly shut down or restart the local operating system via the <xhtml:code>ExitWindowsEx</xhtml:code> or <xhtml:code>InitiateSystemShutdown</xhtml:code> APIs.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Shut down the system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeShutdownPrivilege.ps1">Download Script: Configure-DcUraSeShutdownPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeShutdownPrivilege.ps1
# Configure-DcUraSeShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeShutdownPrivilege\s*=") {
        $NewLines += "SeShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeShutdownPrivilegeStatus.ps1">Download Script: Get-DcUraSeShutdownPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeShutdownPrivilegeStatus.ps1
# Get-DcUraSeShutdownPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seshutdownprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeShutdownPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeShutdownPrivilege.ps1
# Configure-DcUraSeShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeShutdownPrivilege\s*=") {
        $NewLines += "SeShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2133" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-134" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-134] Configure User Rights: Synchronize directory service data on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure).</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-sesyncagentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSyncAgentPrivilege</xhtml:code> grants the caller the authority to initiate directory synchronization operations against Active Directory domain partitions. This privilege is the underlying Windows user right associated with the directory service replication extended rights: <xhtml:code>DS-Replication-Get-Changes</xhtml:code>, <xhtml:code>DS-Replication-Get-Changes-All</xhtml:code>, and <xhtml:code>DS-Replication-Get-Changes-In-Filtered-Set</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Synchronize directory service data`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeSyncAgentPrivilege.ps1">Download Script: Configure-DcUraSeSyncAgentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeSyncAgentPrivilege.ps1
# Configure-DcUraSeSyncAgentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesyncagentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesyncagentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSyncAgentPrivilege\s*=") {
        $NewLines += "SeSyncAgentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSyncAgentPrivilege = ")
    } else {
        $NewLines += "SeSyncAgentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeSyncAgentPrivilegeStatus.ps1">Download Script: Get-DcUraSeSyncAgentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeSyncAgentPrivilegeStatus.ps1
# Get-DcUraSeSyncAgentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesyncagentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSyncAgentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeSyncAgentPrivilege.ps1
# Configure-DcUraSeSyncAgentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesyncagentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesyncagentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSyncAgentPrivilege\s*=") {
        $NewLines += "SeSyncAgentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSyncAgentPrivilege = ")
    } else {
        $NewLines += "SeSyncAgentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2134" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-135" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-135] Configure User Rights: Take ownership of files or other objects on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Tier 0 Active Directory infrastructure). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-112](../../07-paws/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
              <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-122](../../08-endpoints/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, and Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/user-rights/configure-ura-setakeownershipprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTakeOwnershipPrivilege</xhtml:code> allows a user to take ownership of any securable object in the operating system (files, directories, registry keys, Active Directory objects, printers, services) by writing the caller's SID into the object security descriptor owner field via <xhtml:code>SetNamedSecurityInfo</xhtml:code> or <xhtml:code>SetSecurityInfo</xhtml:code>. The Windows security model grants the owner of an object implicit <xhtml:code>WRITE_DAC</xhtml:code> authority.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 Domain Controller systems (e.g., <xhtml:code>Default Domain Controllers Policy</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Take ownership of files or other objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcUraSeTakeOwnershipPrivilege.ps1">Download Script: Configure-DcUraSeTakeOwnershipPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcUraSeTakeOwnershipPrivilege.ps1
# Configure-DcUraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcUraSeTakeOwnershipPrivilegeStatus.ps1">Download Script: Get-DcUraSeTakeOwnershipPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcUraSeTakeOwnershipPrivilegeStatus.ps1
# Get-DcUraSeTakeOwnershipPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setakeownershipprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTakeOwnershipPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcUraSeTakeOwnershipPrivilege.ps1
# Configure-DcUraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2135" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_Services_Hardening">
      <title>Services Hardening</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-035" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-035] Disable Xbox Live Auth Manager on Domain Controllers (XblAuthManager)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-xblauthmanager.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Xbox Live Auth Manager (XblAuthManager) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Provides gaming authentication functions; irrelevant to server infrastructure.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\XblAuthManager</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXblAuthManager.ps1">Download Script: Configure-DisableXblAuthManager.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XblAuthManagerStatus.ps1">Download Script: Get-XblAuthManagerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XblAuthManagerStatus.ps1
# Description: Audits the registry startup state of unnecessary Xbox Live Auth Manager (XblAuthManager) service.

Write-Host "--- Auditing Xbox Live Auth Manager (XblAuthManager) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2035" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-036" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-036] Disable Xbox Live Game Save on Domain Controllers (XblGameSave)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-xblgamesave.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Xbox Live Game Save (XblGameSave) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Provides gaming save functions; irrelevant to server infrastructure.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\XblGameSave</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXblGameSave.ps1">Download Script: Configure-DisableXblGameSave.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XblGameSaveStatus.ps1">Download Script: Get-XblGameSaveStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XblGameSaveStatus.ps1
# Description: Audits the registry startup state of unnecessary Xbox Live Game Save (XblGameSave) service.

Write-Host "--- Auditing Xbox Live Game Save (XblGameSave) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2036" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-037" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-037] Disable ActiveX Installer (AxInstSV) on Domain Controllers (AxInstSV)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-axinstsv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the ActiveX Installer (AxInstSV) (AxInstSV) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Validates ActiveX controls. Domain Controllers should never run ActiveX controls.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\AxInstSV</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableAxInstSV.ps1">Download Script: Configure-DisableAxInstSV.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableAxInstSV.ps1
# Description: Disables the unnecessary ActiveX Installer (AxInstSV) (AxInstSV) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable ActiveX Installer (AxInstSV) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "AxInstSV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-AxInstSVStatus.ps1">Download Script: Get-AxInstSVStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AxInstSVStatus.ps1
# Description: Audits the registry startup state of unnecessary ActiveX Installer (AxInstSV) (AxInstSV) service.

Write-Host "--- Auditing ActiveX Installer (AxInstSV) (AxInstSV) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "AxInstSV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableAxInstSV.ps1
# Description: Disables the unnecessary ActiveX Installer (AxInstSV) (AxInstSV) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable ActiveX Installer (AxInstSV) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "AxInstSV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2037" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-038" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-038] Disable Bluetooth Support Service on Domain Controllers (bthserv)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-bthserv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Bluetooth Support Service (bthserv) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Supports Bluetooth devices; unnecessary on server systems.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\bthserv</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablebthserv.ps1">Download Script: Configure-Disablebthserv.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablebthserv.ps1
# Description: Disables the unnecessary Bluetooth Support Service (bthserv) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Bluetooth Support Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "bthserv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-bthservStatus.ps1">Download Script: Get-bthservStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-bthservStatus.ps1
# Description: Audits the registry startup state of unnecessary Bluetooth Support Service (bthserv) service.

Write-Host "--- Auditing Bluetooth Support Service (bthserv) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "bthserv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablebthserv.ps1
# Description: Disables the unnecessary Bluetooth Support Service (bthserv) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Bluetooth Support Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "bthserv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2038" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-039" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-039] Disable Connected Devices Platform User Service on Domain Controllers (CDPUserSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-cdpusersvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Connected Devices Platform User Service (CDPUserSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Connected Devices Platform User Service; syncs user activity data across devices.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\CDPUserSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableCDPUserSvc.ps1">Download Script: Configure-DisableCDPUserSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableCDPUserSvc.ps1
# Description: Disables the unnecessary Connected Devices Platform User Service (CDPUserSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Connected Devices Platform User Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "CDPUserSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-CDPUserSvcStatus.ps1">Download Script: Get-CDPUserSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-CDPUserSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Connected Devices Platform User Service (CDPUserSvc) service.

Write-Host "--- Auditing Connected Devices Platform User Service (CDPUserSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "CDPUserSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableCDPUserSvc.ps1
# Description: Disables the unnecessary Connected Devices Platform User Service (CDPUserSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Connected Devices Platform User Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "CDPUserSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2039" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-040" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-040] Disable Contact Data on Domain Controllers (PimIndexMaintenanceSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-pimindexmaintenancesvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Contact Data (PimIndexMaintenanceSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Manages contact data indexing; unnecessary on directory servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\PimIndexMaintenanceSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePimIndexMaintenanceSvc.ps1">Download Script: Configure-DisablePimIndexMaintenanceSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePimIndexMaintenanceSvc.ps1
# Description: Disables the unnecessary Contact Data (PimIndexMaintenanceSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Contact Data service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PimIndexMaintenanceSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PimIndexMaintenanceSvcStatus.ps1">Download Script: Get-PimIndexMaintenanceSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PimIndexMaintenanceSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Contact Data (PimIndexMaintenanceSvc) service.

Write-Host "--- Auditing Contact Data (PimIndexMaintenanceSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "PimIndexMaintenanceSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePimIndexMaintenanceSvc.ps1
# Description: Disables the unnecessary Contact Data (PimIndexMaintenanceSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Contact Data service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PimIndexMaintenanceSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2040" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-041" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-041] Disable WAP Push Message Routing Service on Domain Controllers (dmwappushservice)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-dmwappushservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the WAP Push Message Routing Service (dmwappushservice) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>WAP Push Message Routing Service; used for diagnostics and telemetry.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\dmwappushservice</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disabledmwappushservice.ps1">Download Script: Configure-Disabledmwappushservice.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disabledmwappushservice.ps1
# Description: Disables the unnecessary WAP Push Message Routing Service (dmwappushservice) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable WAP Push Message Routing Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "dmwappushservice"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-dmwappushserviceStatus.ps1">Download Script: Get-dmwappushserviceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-dmwappushserviceStatus.ps1
# Description: Audits the registry startup state of unnecessary WAP Push Message Routing Service (dmwappushservice) service.

Write-Host "--- Auditing WAP Push Message Routing Service (dmwappushservice) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "dmwappushservice"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disabledmwappushservice.ps1
# Description: Disables the unnecessary WAP Push Message Routing Service (dmwappushservice) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable WAP Push Message Routing Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "dmwappushservice"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2041" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-042" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-042] Disable Downloaded Maps Manager on Domain Controllers (MapsBroker)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-mapsbroker.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Downloaded Maps Manager (MapsBroker) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Enables access to downloaded maps; irrelevant to server roles.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\MapsBroker</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableMapsBroker.ps1">Download Script: Configure-DisableMapsBroker.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableMapsBroker.ps1
# Description: Disables the unnecessary Downloaded Maps Manager (MapsBroker) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Downloaded Maps Manager service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "MapsBroker"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-MapsBrokerStatus.ps1">Download Script: Get-MapsBrokerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-MapsBrokerStatus.ps1
# Description: Audits the registry startup state of unnecessary Downloaded Maps Manager (MapsBroker) service.

Write-Host "--- Auditing Downloaded Maps Manager (MapsBroker) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "MapsBroker"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableMapsBroker.ps1
# Description: Disables the unnecessary Downloaded Maps Manager (MapsBroker) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Downloaded Maps Manager service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "MapsBroker"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2042" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-043" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-043] Disable Geolocation Service on Domain Controllers (lfsvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-lfsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Geolocation Service (lfsvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Monitors system location; represents a privacy and security risk.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\lfsvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablelfsvc.ps1">Download Script: Configure-Disablelfsvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablelfsvc.ps1
# Description: Disables the unnecessary Geolocation Service (lfsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Geolocation Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "lfsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-lfsvcStatus.ps1">Download Script: Get-lfsvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-lfsvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Geolocation Service (lfsvc) service.

Write-Host "--- Auditing Geolocation Service (lfsvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "lfsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablelfsvc.ps1
# Description: Disables the unnecessary Geolocation Service (lfsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Geolocation Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "lfsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2043" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-044" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-044] Disable Internet Connection Sharing (ICS) on Domain Controllers (SharedAccess)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-sharedaccess.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Internet Connection Sharing (ICS) (SharedAccess) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Provides network address translation; represents a networking security risk.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\SharedAccess</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSharedAccess.ps1">Download Script: Configure-DisableSharedAccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SharedAccessStatus.ps1">Download Script: Get-SharedAccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SharedAccessStatus.ps1
# Description: Audits the registry startup state of unnecessary Internet Connection Sharing (ICS) (SharedAccess) service.

Write-Host "--- Auditing Internet Connection Sharing (ICS) (SharedAccess) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2044" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-045" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-045] Disable Link-Layer Topology Discovery Mapper on Domain Controllers (lltdsvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-lltdsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Link-Layer Topology Discovery Mapper (lltdsvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Discovers network topology; unnecessary exposure of server network location.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\lltdsvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablelltdsvc.ps1">Download Script: Configure-Disablelltdsvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablelltdsvc.ps1
# Description: Disables the unnecessary Link-Layer Topology Discovery Mapper (lltdsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Link-Layer Topology Discovery Mapper service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "lltdsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-lltdsvcStatus.ps1">Download Script: Get-lltdsvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-lltdsvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Link-Layer Topology Discovery Mapper (lltdsvc) service.

Write-Host "--- Auditing Link-Layer Topology Discovery Mapper (lltdsvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "lltdsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablelltdsvc.ps1
# Description: Disables the unnecessary Link-Layer Topology Discovery Mapper (lltdsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Link-Layer Topology Discovery Mapper service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "lltdsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2045" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-046" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-046] Disable Microsoft Account Sign-in Assistant on Domain Controllers (wlidsvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-wlidsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Microsoft Account Sign-in Assistant (wlidsvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Enables user signing with Microsoft Accounts; unnecessary on directory servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\wlidsvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablewlidsvc.ps1">Download Script: Configure-Disablewlidsvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablewlidsvc.ps1
# Description: Disables the unnecessary Microsoft Account Sign-in Assistant (wlidsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Account Sign-in Assistant service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "wlidsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-wlidsvcStatus.ps1">Download Script: Get-wlidsvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-wlidsvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Microsoft Account Sign-in Assistant (wlidsvc) service.

Write-Host "--- Auditing Microsoft Account Sign-in Assistant (wlidsvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "wlidsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablewlidsvc.ps1
# Description: Disables the unnecessary Microsoft Account Sign-in Assistant (wlidsvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Account Sign-in Assistant service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "wlidsvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2046" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-047" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-047] Disable Microsoft Passport on Domain Controllers (NgcSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-ngcsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Microsoft Passport (NgcSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Part of Windows Hello for Business; not needed if Windows Hello is not deployed.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\NgcSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableNgcSvc.ps1">Download Script: Configure-DisableNgcSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableNgcSvc.ps1
# Description: Disables the unnecessary Microsoft Passport (NgcSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Passport service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NgcSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-NgcSvcStatus.ps1">Download Script: Get-NgcSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-NgcSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Microsoft Passport (NgcSvc) service.

Write-Host "--- Auditing Microsoft Passport (NgcSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "NgcSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableNgcSvc.ps1
# Description: Disables the unnecessary Microsoft Passport (NgcSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Passport service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NgcSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2047" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-048" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-048] Disable Microsoft Passport Container on Domain Controllers (NgcCtnrSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-ngcctnrsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Microsoft Passport Container (NgcCtnrSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Part of Windows Hello for Business container management.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\NgcCtnrSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableNgcCtnrSvc.ps1">Download Script: Configure-DisableNgcCtnrSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableNgcCtnrSvc.ps1
# Description: Disables the unnecessary Microsoft Passport Container (NgcCtnrSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Passport Container service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NgcCtnrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-NgcCtnrSvcStatus.ps1">Download Script: Get-NgcCtnrSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-NgcCtnrSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Microsoft Passport Container (NgcCtnrSvc) service.

Write-Host "--- Auditing Microsoft Passport Container (NgcCtnrSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "NgcCtnrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableNgcCtnrSvc.ps1
# Description: Disables the unnecessary Microsoft Passport Container (NgcCtnrSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Microsoft Passport Container service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NgcCtnrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2048" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-049" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-049] Disable Network Connection Broker on Domain Controllers (NcbService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-ncbservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Network Connection Broker (NcbService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Broker for background network connections for modern apps.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\NcbService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableNcbService.ps1">Download Script: Configure-DisableNcbService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableNcbService.ps1
# Description: Disables the unnecessary Network Connection Broker (NcbService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Network Connection Broker service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NcbService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-NcbServiceStatus.ps1">Download Script: Get-NcbServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-NcbServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary Network Connection Broker (NcbService) service.

Write-Host "--- Auditing Network Connection Broker (NcbService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "NcbService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableNcbService.ps1
# Description: Disables the unnecessary Network Connection Broker (NcbService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Network Connection Broker service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "NcbService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2049" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-050" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-050] Disable Phone Service on Domain Controllers (PhoneSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-phonesvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Phone Service (PhoneSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Manages telephony state; irrelevant to server infrastructure.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\PhoneSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePhoneSvc.ps1">Download Script: Configure-DisablePhoneSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePhoneSvc.ps1
# Description: Disables the unnecessary Phone Service (PhoneSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Phone Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PhoneSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PhoneSvcStatus.ps1">Download Script: Get-PhoneSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PhoneSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Phone Service (PhoneSvc) service.

Write-Host "--- Auditing Phone Service (PhoneSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "PhoneSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePhoneSvc.ps1
# Description: Disables the unnecessary Phone Service (PhoneSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Phone Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PhoneSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2050" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-051" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-051] Disable Printer Extensions and Notifications on Domain Controllers (PrintNotify)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-printnotify.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Printer Extensions and Notifications (PrintNotify) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Handles printer notification dialogs; unnecessary on servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\PrintNotify</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePrintNotify.ps1">Download Script: Configure-DisablePrintNotify.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePrintNotify.ps1
# Description: Disables the unnecessary Printer Extensions and Notifications (PrintNotify) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Printer Extensions and Notifications service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PrintNotify"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PrintNotifyStatus.ps1">Download Script: Get-PrintNotifyStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PrintNotifyStatus.ps1
# Description: Audits the registry startup state of unnecessary Printer Extensions and Notifications (PrintNotify) service.

Write-Host "--- Auditing Printer Extensions and Notifications (PrintNotify) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "PrintNotify"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePrintNotify.ps1
# Description: Disables the unnecessary Printer Extensions and Notifications (PrintNotify) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Printer Extensions and Notifications service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PrintNotify"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2051" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-052" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-052] Disable Program Compatibility Assistant Service on Domain Controllers (PcaSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-pcasvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Program Compatibility Assistant Service (PcaSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Detects application compatibility issues; unnecessary on highly controlled DCs.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\PcaSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePcaSvc.ps1">Download Script: Configure-DisablePcaSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePcaSvc.ps1
# Description: Disables the unnecessary Program Compatibility Assistant Service (PcaSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Program Compatibility Assistant Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PcaSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PcaSvcStatus.ps1">Download Script: Get-PcaSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PcaSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Program Compatibility Assistant Service (PcaSvc) service.

Write-Host "--- Auditing Program Compatibility Assistant Service (PcaSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "PcaSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePcaSvc.ps1
# Description: Disables the unnecessary Program Compatibility Assistant Service (PcaSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Program Compatibility Assistant Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "PcaSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2052" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-053" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-053] Disable Quality Windows Audio Video Experience on Domain Controllers (QWAVE)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-qwave.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Quality Windows Audio Video Experience (QWAVE) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Multimedia streaming quality service; irrelevant to server systems.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\QWAVE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableQWAVE.ps1">Download Script: Configure-DisableQWAVE.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableQWAVE.ps1
# Description: Disables the unnecessary Quality Windows Audio Video Experience (QWAVE) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Quality Windows Audio Video Experience service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "QWAVE"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-QWAVEStatus.ps1">Download Script: Get-QWAVEStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-QWAVEStatus.ps1
# Description: Audits the registry startup state of unnecessary Quality Windows Audio Video Experience (QWAVE) service.

Write-Host "--- Auditing Quality Windows Audio Video Experience (QWAVE) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "QWAVE"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableQWAVE.ps1
# Description: Disables the unnecessary Quality Windows Audio Video Experience (QWAVE) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Quality Windows Audio Video Experience service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "QWAVE"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2053" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-054" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-054] Disable Radio Management Service on Domain Controllers (RmSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-rmsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Radio Management Service (RmSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Controls radio transmitters (cellular, Wi-Fi); irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\RmSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableRmSvc.ps1">Download Script: Configure-DisableRmSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableRmSvc.ps1
# Description: Disables the unnecessary Radio Management Service (RmSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Radio Management Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "RmSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-RmSvcStatus.ps1">Download Script: Get-RmSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-RmSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Radio Management Service (RmSvc) service.

Write-Host "--- Auditing Radio Management Service (RmSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "RmSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableRmSvc.ps1
# Description: Disables the unnecessary Radio Management Service (RmSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Radio Management Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "RmSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2054" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-055" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-055] Disable Sensor Data Service on Domain Controllers (SensorDataService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-sensordataservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Sensor Data Service (SensorDataService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Handles data from system sensors; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\SensorDataService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSensorDataService.ps1">Download Script: Configure-DisableSensorDataService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSensorDataService.ps1
# Description: Disables the unnecessary Sensor Data Service (SensorDataService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Data Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensorDataService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SensorDataServiceStatus.ps1">Download Script: Get-SensorDataServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SensorDataServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary Sensor Data Service (SensorDataService) service.

Write-Host "--- Auditing Sensor Data Service (SensorDataService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "SensorDataService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSensorDataService.ps1
# Description: Disables the unnecessary Sensor Data Service (SensorDataService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Data Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensorDataService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2055" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-056" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-056] Disable Sensor Monitoring Service on Domain Controllers (SensrSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-sensrsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Sensor Monitoring Service (SensrSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Monitors system sensors; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\SensrSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSensrSvc.ps1">Download Script: Configure-DisableSensrSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSensrSvc.ps1
# Description: Disables the unnecessary Sensor Monitoring Service (SensrSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Monitoring Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SensrSvcStatus.ps1">Download Script: Get-SensrSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SensrSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Sensor Monitoring Service (SensrSvc) service.

Write-Host "--- Auditing Sensor Monitoring Service (SensrSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "SensrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSensrSvc.ps1
# Description: Disables the unnecessary Sensor Monitoring Service (SensrSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Monitoring Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensrSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2056" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-057" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-057] Disable Sensor Service on Domain Controllers (SensorService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-sensorservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Sensor Service (SensorService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Core sensor service; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\SensorService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSensorService.ps1">Download Script: Configure-DisableSensorService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSensorService.ps1
# Description: Disables the unnecessary Sensor Service (SensorService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensorService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SensorServiceStatus.ps1">Download Script: Get-SensorServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SensorServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary Sensor Service (SensorService) service.

Write-Host "--- Auditing Sensor Service (SensorService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "SensorService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSensorService.ps1
# Description: Disables the unnecessary Sensor Service (SensorService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sensor Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SensorService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2057" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-058" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-058] Disable Shell Hardware Detection on Domain Controllers (ShellHWDetection)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-shellhwdetection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Shell Hardware Detection (ShellHWDetection) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Provides notifications for AutoPlay hardware events; can be disabled.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\ShellHWDetection</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableShellHWDetection.ps1">Download Script: Configure-DisableShellHWDetection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableShellHWDetection.ps1
# Description: Disables the unnecessary Shell Hardware Detection (ShellHWDetection) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Shell Hardware Detection service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "ShellHWDetection"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-ShellHWDetectionStatus.ps1">Download Script: Get-ShellHWDetectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-ShellHWDetectionStatus.ps1
# Description: Audits the registry startup state of unnecessary Shell Hardware Detection (ShellHWDetection) service.

Write-Host "--- Auditing Shell Hardware Detection (ShellHWDetection) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "ShellHWDetection"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableShellHWDetection.ps1
# Description: Disables the unnecessary Shell Hardware Detection (ShellHWDetection) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Shell Hardware Detection service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "ShellHWDetection"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2058" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-059" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-059] Disable Smart Card Device Enumeration Service on Domain Controllers (ScDeviceEnum)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-scdeviceenum.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Smart Card Device Enumeration Service (ScDeviceEnum) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Detects smart cards; can be disabled if smart cards are not used for authentication.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\ScDeviceEnum</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableScDeviceEnum.ps1">Download Script: Configure-DisableScDeviceEnum.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableScDeviceEnum.ps1
# Description: Disables the unnecessary Smart Card Device Enumeration Service (ScDeviceEnum) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Smart Card Device Enumeration Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "ScDeviceEnum"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-ScDeviceEnumStatus.ps1">Download Script: Get-ScDeviceEnumStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-ScDeviceEnumStatus.ps1
# Description: Audits the registry startup state of unnecessary Smart Card Device Enumeration Service (ScDeviceEnum) service.

Write-Host "--- Auditing Smart Card Device Enumeration Service (ScDeviceEnum) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "ScDeviceEnum"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableScDeviceEnum.ps1
# Description: Disables the unnecessary Smart Card Device Enumeration Service (ScDeviceEnum) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Smart Card Device Enumeration Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "ScDeviceEnum"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2059" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-060" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-060] Disable SSDP Discovery on Domain Controllers (SSDPSRV)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-ssdpsrv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the SSDP Discovery (SSDPSRV) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Discovers UPnP devices; introduces broadcast name discovery vulnerabilities.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\SSDPSRV</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSSDPSRV.ps1">Download Script: Configure-DisableSSDPSRV.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SSDPSRVStatus.ps1">Download Script: Get-SSDPSRVStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SSDPSRVStatus.ps1
# Description: Audits the registry startup state of unnecessary SSDP Discovery (SSDPSRV) service.

Write-Host "--- Auditing SSDP Discovery (SSDPSRV) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2060" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-061" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-061] Disable Still Image Acquisition Events on Domain Controllers (WiaRpc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-wiarpc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Still Image Acquisition Events (WiaRpc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Still image capturing events; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\WiaRpc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWiaRpc.ps1">Download Script: Configure-DisableWiaRpc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWiaRpc.ps1
# Description: Disables the unnecessary Still Image Acquisition Events (WiaRpc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Still Image Acquisition Events service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WiaRpc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WiaRpcStatus.ps1">Download Script: Get-WiaRpcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WiaRpcStatus.ps1
# Description: Audits the registry startup state of unnecessary Still Image Acquisition Events (WiaRpc) service.

Write-Host "--- Auditing Still Image Acquisition Events (WiaRpc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "WiaRpc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWiaRpc.ps1
# Description: Disables the unnecessary Still Image Acquisition Events (WiaRpc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Still Image Acquisition Events service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WiaRpc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2061" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-062" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-062] Disable Sync Host on Domain Controllers (OneSyncSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-onesyncsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Sync Host (OneSyncSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Synchronizes mail, contacts, calendar; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\OneSyncSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableOneSyncSvc.ps1">Download Script: Configure-DisableOneSyncSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableOneSyncSvc.ps1
# Description: Disables the unnecessary Sync Host (OneSyncSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sync Host service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "OneSyncSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-OneSyncSvcStatus.ps1">Download Script: Get-OneSyncSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-OneSyncSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Sync Host (OneSyncSvc) service.

Write-Host "--- Auditing Sync Host (OneSyncSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "OneSyncSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableOneSyncSvc.ps1
# Description: Disables the unnecessary Sync Host (OneSyncSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Sync Host service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "OneSyncSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2062" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-063" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-063] Disable UPnP Device Host on Domain Controllers (upnphost)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-upnphost.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the UPnP Device Host (upnphost) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Allows hosting of UPnP devices; represents unnecessary network exposure.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\upnphost</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disableupnphost.ps1">Download Script: Configure-Disableupnphost.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disableupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-upnphostStatus.ps1">Download Script: Get-upnphostStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-upnphostStatus.ps1
# Description: Audits the registry startup state of unnecessary UPnP Device Host (upnphost) service.

Write-Host "--- Auditing UPnP Device Host (upnphost) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disableupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2063" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-064" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-064] Disable User Data Access on Domain Controllers (UserDataSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-userdatasvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the User Data Access (UserDataSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Manages user structured data; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\UserDataSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableUserDataSvc.ps1">Download Script: Configure-DisableUserDataSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableUserDataSvc.ps1
# Description: Disables the unnecessary User Data Access (UserDataSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable User Data Access service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "UserDataSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UserDataSvcStatus.ps1">Download Script: Get-UserDataSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UserDataSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary User Data Access (UserDataSvc) service.

Write-Host "--- Auditing User Data Access (UserDataSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "UserDataSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableUserDataSvc.ps1
# Description: Disables the unnecessary User Data Access (UserDataSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable User Data Access service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "UserDataSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2064" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-065" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-065] Disable User Data Storage on Domain Controllers (UnistoreSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-unistoresvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the User Data Storage (UnistoreSvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Stores user data; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\UnistoreSvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableUnistoreSvc.ps1">Download Script: Configure-DisableUnistoreSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableUnistoreSvc.ps1
# Description: Disables the unnecessary User Data Storage (UnistoreSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable User Data Storage service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "UnistoreSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UnistoreSvcStatus.ps1">Download Script: Get-UnistoreSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UnistoreSvcStatus.ps1
# Description: Audits the registry startup state of unnecessary User Data Storage (UnistoreSvc) service.

Write-Host "--- Auditing User Data Storage (UnistoreSvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "UnistoreSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableUnistoreSvc.ps1
# Description: Disables the unnecessary User Data Storage (UnistoreSvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable User Data Storage service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "UnistoreSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2065" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-066" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-066] Disable WalletService on Domain Controllers (WalletService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-walletservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the WalletService (WalletService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Used by Wallet application; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\WalletService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWalletService.ps1">Download Script: Configure-DisableWalletService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWalletService.ps1
# Description: Disables the unnecessary WalletService (WalletService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable WalletService service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WalletService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WalletServiceStatus.ps1">Download Script: Get-WalletServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WalletServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary WalletService (WalletService) service.

Write-Host "--- Auditing WalletService (WalletService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "WalletService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWalletService.ps1
# Description: Disables the unnecessary WalletService (WalletService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable WalletService service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WalletService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2066" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-067" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-067] Disable Windows Audio on Domain Controllers (Audiosrv)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-audiosrv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Audio (Audiosrv) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Manages system audio; servers do not require audio capabilities.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Audiosrv</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableAudiosrv.ps1">Download Script: Configure-DisableAudiosrv.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableAudiosrv.ps1
# Description: Disables the unnecessary Windows Audio (Audiosrv) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Audio service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "Audiosrv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-AudiosrvStatus.ps1">Download Script: Get-AudiosrvStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AudiosrvStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Audio (Audiosrv) service.

Write-Host "--- Auditing Windows Audio (Audiosrv) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "Audiosrv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableAudiosrv.ps1
# Description: Disables the unnecessary Windows Audio (Audiosrv) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Audio service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "Audiosrv"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2067" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-068" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-068] Disable Windows Audio Endpoint Builder on Domain Controllers (AudioEndpointBuilder)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-audioendpointbuilder.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Audio Endpoint Builder (AudioEndpointBuilder) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Manages audio endpoints; servers do not require audio capabilities.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\AudioEndpointBuilder</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableAudioEndpointBuilder.ps1">Download Script: Configure-DisableAudioEndpointBuilder.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableAudioEndpointBuilder.ps1
# Description: Disables the unnecessary Windows Audio Endpoint Builder (AudioEndpointBuilder) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Audio Endpoint Builder service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "AudioEndpointBuilder"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-AudioEndpointBuilderStatus.ps1">Download Script: Get-AudioEndpointBuilderStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AudioEndpointBuilderStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Audio Endpoint Builder (AudioEndpointBuilder) service.

Write-Host "--- Auditing Windows Audio Endpoint Builder (AudioEndpointBuilder) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "AudioEndpointBuilder"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableAudioEndpointBuilder.ps1
# Description: Disables the unnecessary Windows Audio Endpoint Builder (AudioEndpointBuilder) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Audio Endpoint Builder service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "AudioEndpointBuilder"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2068" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-069" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-069] Disable Windows Camera Frame Server on Domain Controllers (FrameServer)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-frameserver.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Camera Frame Server (FrameServer) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Enables access to system camera feeds; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\FrameServer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableFrameServer.ps1">Download Script: Configure-DisableFrameServer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableFrameServer.ps1
# Description: Disables the unnecessary Windows Camera Frame Server (FrameServer) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Camera Frame Server service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "FrameServer"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-FrameServerStatus.ps1">Download Script: Get-FrameServerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-FrameServerStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Camera Frame Server (FrameServer) service.

Write-Host "--- Auditing Windows Camera Frame Server (FrameServer) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "FrameServer"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableFrameServer.ps1
# Description: Disables the unnecessary Windows Camera Frame Server (FrameServer) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Camera Frame Server service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "FrameServer"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2069" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-070" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-070] Disable Windows Image Acquisition (WIA) on Domain Controllers (stisvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-stisvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Image Acquisition (WIA) (stisvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Image acquisition from scanners/cameras; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\stisvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablestisvc.ps1">Download Script: Configure-Disablestisvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablestisvc.ps1
# Description: Disables the unnecessary Windows Image Acquisition (WIA) (stisvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Image Acquisition (WIA) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "stisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-stisvcStatus.ps1">Download Script: Get-stisvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-stisvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Image Acquisition (WIA) (stisvc) service.

Write-Host "--- Auditing Windows Image Acquisition (WIA) (stisvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "stisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablestisvc.ps1
# Description: Disables the unnecessary Windows Image Acquisition (WIA) (stisvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Image Acquisition (WIA) service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "stisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2070" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-071" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-071] Disable Windows Insider Service on Domain Controllers (wisvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-wisvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Insider Service (wisvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Handles Windows Insider settings; unnecessary on production servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\wisvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablewisvc.ps1">Download Script: Configure-Disablewisvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablewisvc.ps1
# Description: Disables the unnecessary Windows Insider Service (wisvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Insider Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "wisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-wisvcStatus.ps1">Download Script: Get-wisvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-wisvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Insider Service (wisvc) service.

Write-Host "--- Auditing Windows Insider Service (wisvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "wisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablewisvc.ps1
# Description: Disables the unnecessary Windows Insider Service (wisvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Insider Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "wisvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2071" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-072" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-072] Disable Windows Mobile Hotspot Service on Domain Controllers (icssvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-icssvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Mobile Hotspot Service (icssvc) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Shares internet connection as hotspot; introduces wireless routing security risk.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\icssvc</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disableicssvc.ps1">Download Script: Configure-Disableicssvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disableicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-icssvcStatus.ps1">Download Script: Get-icssvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-icssvcStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Mobile Hotspot Service (icssvc) service.

Write-Host "--- Auditing Windows Mobile Hotspot Service (icssvc) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disableicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2072" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-073" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-073] Disable Windows Push Notifications System Service on Domain Controllers (WpnService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-wpnservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Push Notifications System Service (WpnService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>System service for push notifications; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\WpnService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWpnService.ps1">Download Script: Configure-DisableWpnService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWpnService.ps1
# Description: Disables the unnecessary Windows Push Notifications System Service (WpnService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Push Notifications System Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WpnService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WpnServiceStatus.ps1">Download Script: Get-WpnServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WpnServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Push Notifications System Service (WpnService) service.

Write-Host "--- Auditing Windows Push Notifications System Service (WpnService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "WpnService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWpnService.ps1
# Description: Disables the unnecessary Windows Push Notifications System Service (WpnService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Push Notifications System Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WpnService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2073" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-074" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-074] Disable Windows Push Notifications User Service on Domain Controllers (WpnUserService)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-wpnuserservice.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Domain Controllers represent the highest privilege tier (Tier 0) in the Active Directory forest. Minimizing the execution footprint on these critical servers is an essential hardening guideline. Disabling the Windows Push Notifications User Service (WpnUserService) service directly supports this:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>User service for push notifications; irrelevant to servers.</xhtml:li>
            <xhtml:li>Reducing running background services closes potential vectors for local privilege escalation and memory space exploits on the directory controllers.</xhtml:li>
          </xhtml:ol>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:p>Because these services are not managed through standard GPO Administrative Templates, configure Group Policy Preferences (GPP) for the registry:</xhtml:p>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
            <xhtml:li>Edit the GPO linked to your Domain Controllers Organizational Unit (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a new Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\WpnUserService</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>Start</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>4</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWpnUserService.ps1">Download Script: Configure-DisableWpnUserService.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWpnUserService.ps1
# Description: Disables the unnecessary Windows Push Notifications User Service (WpnUserService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Push Notifications User Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WpnUserService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WpnUserServiceStatus.ps1">Download Script: Get-WpnUserServiceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WpnUserServiceStatus.ps1
# Description: Audits the registry startup state of unnecessary Windows Push Notifications User Service (WpnUserService) service.

Write-Host "--- Auditing Windows Push Notifications User Service (WpnUserService) Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "WpnUserService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWpnUserService.ps1
# Description: Disables the unnecessary Windows Push Notifications User Service (WpnUserService) service on Domain Controllers.

Write-Host "Applying hardening requirement: Disable Windows Push Notifications User Service service on Domain Controllers..." -ForegroundColor Cyan

$ServiceName = "WpnUserService"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2074" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-146" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-146] Disable WebClient Service (WebClient)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (DCs) running Windows Server.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/services/disable-webclient.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The WebClient service enables Windows-based programs to create, access, and modify Internet-based files via the Web Distributed Authoring and Versioning (WebDAV) protocol.</xhtml:p>
          <xhtml:p>In an Active Directory environment, the WebClient service represents a major credential coercion and relay attack surface: 1. <xhtml:strong>Bypassing SMB Signing</xhtml:strong>: WebDAV coercion triggers an outbound HTTP/HTTPS connection using NTLM authentication rather than SMB. Because HTTP authentication does not enforce SMB signing, an attacker can coerce a Domain Controller (e.g., via PetitPotam, DFSCoerce, or ShadowCoerce targeting a WebDAV path like <xhtml:code>\\attacker@80\share\test</xhtml:code>) and relay the coerced machine account NTLM credentials directly to LDAP/LDAPS, Active Directory Certificate Services (AD CS) Web Enrollment, or other critical directory endpoints. 2. <xhtml:strong>Principle of Least Functionality</xhtml:strong>: Domain Controllers perform core directory and authentication functions and must never operate as WebDAV clients to external or internal web servers.</xhtml:p>
          <xhtml:p>Stopping and disabling the WebClient service on Domain Controllers completely neutralizes WebDAV-based coercion and cross-protocol relay vectors.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the Domain Controllers GPO (e.g., <xhtml:code>GPO_Hardening_DC</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>WebClient</xhtml:code>, double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWebClient.ps1">Download Script: Configure-DisableWebClient.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWebClient.ps1
# Description: Disables the WebClient service on the Domain Controller to eliminate WebDAV coercion and relay attacks.

Write-Host "Applying hardening requirement: Disable WebClient service on Domain Controller..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup configuration of the WebClient service on the Domain Controller:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WebClientStatus.ps1">Download Script: Get-WebClientStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WebClientStatus.ps1
# Description: Audits the startup configuration of the WebClient service on the Domain Controller.

Write-Host "--- Auditing WebClient Service on Domain Controller ---" -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWebClient.ps1
# Description: Disables the WebClient service on the Domain Controller to eliminate WebDAV coercion and relay attacks.

Write-Host "Applying hardening requirement: Disable WebClient service on Domain Controller..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2146" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_Advanced_Security_Audit_Policies">
      <title>Advanced Security Audit Policies</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-136" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-136] Audit Policy: Advanced Audit Policy Overrides on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-audit-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing advanced audit policy overrides prevents legacy category settings from overriding refined subcategory policies, and disabling verbose Kerberos logging ensures that event logs are not flooded with diagnostic events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\System\CurrentControlSet\Control\Lsa\ SCENoApplyLegacyAuditPolicy</xhtml:code> = <xhtml:code>1</xhtml:code> (DWord)</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters\ LogLevel</xhtml:code> = <xhtml:code>0</xhtml:code> (DWord)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditAuditoverride.ps1">Download Script: Configure-DcAuditAuditoverride.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditAuditoverrideStatus.ps1">Download Script: Get-DcAuditAuditoverrideStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditAuditoverrideStatus.ps1
$script:Vulnerable = $false

# Audit Registry: SCENoApplyLegacyAuditPolicy
$RegVal = Get-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.SCENoApplyLegacyAuditPolicy -ne 1) {
    $script:Vulnerable = $true
}

# Audit Registry: LogLevel
$RegVal = Get-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LogLevel -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2136" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-137" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-137] Audit Policy: Account Logon Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-account-logon.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account logon events captures authentication requests processed by the local system or the domain controller, which is critical for identifying Kerberoasting, NTLM relaying, and brute-force attempts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Kerberos Authentication Service</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Kerberos Service Ticket Operations</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Credential Validation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditAccountlogon.ps1">Download Script: Configure-DcAuditAccountlogon.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Kerberos Authentication Service
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Kerberos Authentication Service`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Kerberos Authentication Service to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Kerberos Authentication Service. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Kerberos Service Ticket Operations
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Kerberos Service Ticket Operations`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Kerberos Service Ticket Operations to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Kerberos Service Ticket Operations. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditAccountlogonStatus.ps1">Download Script: Get-DcAuditAccountlogonStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditAccountlogonStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Kerberos Authentication Service
$RawOutput = auditpol.exe /get /subcategory:"Kerberos Authentication Service" /r
if ($RawOutput -notmatch ",Kerberos Authentication Service,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Kerberos Service Ticket Operations
$RawOutput = auditpol.exe /get /subcategory:"Kerberos Service Ticket Operations" /r
if ($RawOutput -notmatch ",Kerberos Service Ticket Operations,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Credential Validation
$RawOutput = auditpol.exe /get /subcategory:"Credential Validation" /r
if ($RawOutput -notmatch ",Credential Validation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Kerberos Authentication Service
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Kerberos Authentication Service`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Kerberos Authentication Service to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Kerberos Authentication Service. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Kerberos Service Ticket Operations
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Kerberos Service Ticket Operations`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Kerberos Service Ticket Operations to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Kerberos Service Ticket Operations. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2137" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-138" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-138] Audit Policy: Account Management Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-account-management.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account management logs security principal modifications (creations, deletions, password resets, group modifications) to detect privilege escalation attempts on domain or local administrative groups.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>User Account Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security Group Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Application Group Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Computer Account Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Distribution Group Management</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Account Management Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditAccountmanagement.ps1">Download Script: Configure-DcAuditAccountmanagement.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Application Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Application Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Application Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Application Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Computer Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Computer Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Computer Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Computer Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Distribution Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Distribution Group Management`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Distribution Group Management to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Distribution Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditAccountmanagementStatus.ps1">Download Script: Get-DcAuditAccountmanagementStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditAccountmanagementStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: User Account Management
$RawOutput = auditpol.exe /get /subcategory:"User Account Management" /r
if ($RawOutput -notmatch ",User Account Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security Group Management
$RawOutput = auditpol.exe /get /subcategory:"Security Group Management" /r
if ($RawOutput -notmatch ",Security Group Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Application Group Management
$RawOutput = auditpol.exe /get /subcategory:"Application Group Management" /r
if ($RawOutput -notmatch ",Application Group Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Computer Account Management
$RawOutput = auditpol.exe /get /subcategory:"Computer Account Management" /r
if ($RawOutput -notmatch ",Computer Account Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Distribution Group Management
$RawOutput = auditpol.exe /get /subcategory:"Distribution Group Management" /r
if ($RawOutput -notmatch ",Distribution Group Management,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Account Management Events
$RawOutput = auditpol.exe /get /subcategory:"Other Account Management Events" /r
if ($RawOutput -notmatch ",Other Account Management Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Application Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Application Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Application Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Application Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Computer Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Computer Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Computer Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Computer Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Distribution Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Distribution Group Management`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Distribution Group Management to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Distribution Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2138" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-139" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-139] Audit Policy: Detailed Tracking Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-detailed-tracking.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Detailed tracking records process creations and device arrivals to ensure EDR/SIEM visibility into executable command lines and hardware plug events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Process Creation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>DPAPI Activity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>PNP Activity</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditDetailedtracking.ps1">Download Script: Configure-DcAuditDetailedtracking.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditDetailedtrackingStatus.ps1">Download Script: Get-DcAuditDetailedtrackingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditDetailedtrackingStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Process Creation
$RawOutput = auditpol.exe /get /subcategory:"Process Creation" /r
if ($RawOutput -notmatch ",Process Creation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: DPAPI Activity
$RawOutput = auditpol.exe /get /subcategory:"DPAPI Activity" /r
if ($RawOutput -notmatch ",DPAPI Activity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: PNP Activity
$RawOutput = auditpol.exe /get /subcategory:"PNP Activity" /r
if ($RawOutput -notmatch ",PNP Activity,.*,Success") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2139" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-140" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-140] Audit Policy: Directory Service Access Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-ds-access.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing Directory Service changes captures creations, modifications, and deletions of Active Directory objects, providing an essential trail for monitoring structural domain modifications.</xhtml:p>
          <xhtml:p>Key security telemetry enabled by these subcategories includes: 1. <xhtml:strong>Shadow Credentials Detection (Event ID 5136)</xhtml:strong>: Placing a System Access Control List (SACL) on the <xhtml:code>msDS-KeyCredentialLink</xhtml:code> attribute across user and computer objects combined with <xhtml:code>Directory Service Changes</xhtml:code> auditing generates Event ID <xhtml:code>5136</xhtml:code> whenever an attacker attempts to inject raw X.509 certificate credentials (<xhtml:code>pywhisker</xhtml:code>, <xhtml:code>PKINITtools</xhtml:code>) to gain Kerberos PKINIT persistence or account takeover. 2. <xhtml:strong>DCSync &amp; Replication Rights Auditing (Event ID 4662)</xhtml:strong>: Auditing <xhtml:code>Directory Service Access</xhtml:code> with SACLs placed on the Domain Root container generates Event ID <xhtml:code>4662</xhtml:code> when an attacker or unauthorized identity attempts DRSUAPI replication calls (<xhtml:code>DS-Replication-Get-Changes-All</xhtml:code>). 3. <xhtml:strong>Privileged Group &amp; ACL Tampering</xhtml:strong>: Provides immediate visibility into unauthorized modifications to administrative groups (<xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Enterprise Admins</xhtml:code>, <xhtml:code>DnsAdmins</xhtml:code>) and <xhtml:code>adminSDHolder</xhtml:code> permission descriptors.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory settings matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Directory Service Changes</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Directory Service Access</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure Active Directory SACLs on sensitive containers:</xhtml:li>
            <xhtml:li>
              <xhtml:em> To audit Shadow Credentials, open `ADSI Edit` (`adsiedit.msc`), navigate to target organizational units (e.g. `OU=Tier0,DC=corp,DC=local`), right-click -&gt; </xhtml:em>
              <xhtml:em>Properties</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>Security</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>Advanced</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>Auditing</xhtml:em>* tab. Add an audit entry for <xhtml:code>Everyone</xhtml:code> covering <xhtml:code>Write msDS-KeyCredentialLink</xhtml:code> (Type: <xhtml:code>All</xhtml:code>).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditDsaccess.ps1">Download Script: Configure-DcAuditDsaccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditDsaccess.ps1
Write-Host "Applying Audit Policy category: ds-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Directory Service Changes
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Directory Service Changes`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Directory Service Changes to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Directory Service Changes. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Directory Service Access
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Directory Service Access`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Directory Service Access to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Directory Service Access. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditDsaccessStatus.ps1">Download Script: Get-DcAuditDsaccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditDsaccessStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Directory Service Changes
$RawOutput = auditpol.exe /get /subcategory:"Directory Service Changes" /r
if ($RawOutput -notmatch ",Directory Service Changes,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Directory Service Access
$RawOutput = auditpol.exe /get /subcategory:"Directory Service Access" /r
if ($RawOutput -notmatch ",Directory Service Access,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditDsaccess.ps1
Write-Host "Applying Audit Policy category: ds-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Directory Service Changes
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Directory Service Changes`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Directory Service Changes to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Directory Service Changes. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Directory Service Access
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Directory Service Access`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Directory Service Access to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Directory Service Access. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2140" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-141" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-141] Audit Policy: Logon and Logoff Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-logon-logoff.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing logon/logoff events monitors administrative session states, special elevations, and failed logon attempts, which is critical for finding unauthorized remote access or lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logoff</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Special Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Account Lockout</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Logon/Logoff Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditLogonlogoff.ps1">Download Script: Configure-DcAuditLogonlogoff.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditLogonlogoffStatus.ps1">Download Script: Get-DcAuditLogonlogoffStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditLogonlogoffStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Logon
$RawOutput = auditpol.exe /get /subcategory:"Logon" /r
if ($RawOutput -notmatch ",Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Logoff
$RawOutput = auditpol.exe /get /subcategory:"Logoff" /r
if ($RawOutput -notmatch ",Logoff,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Special Logon
$RawOutput = auditpol.exe /get /subcategory:"Special Logon" /r
if ($RawOutput -notmatch ",Special Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Account Lockout
$RawOutput = auditpol.exe /get /subcategory:"Account Lockout" /r
if ($RawOutput -notmatch ",Account Lockout,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Logon/Logoff Events
$RawOutput = auditpol.exe /get /subcategory:"Other Logon/Logoff Events" /r
if ($RawOutput -notmatch ",Other Logon/Logoff Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2141" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-142" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-142] Audit Policy: Object Access Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-object-access.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing object access (files, registry keys, and shares) helps monitor unauthorized modifications to system configuration files and access to restricted shares.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Handle Manipulation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Registry</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>File Share</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Detailed File Share</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Object Access Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditObjectaccess.ps1">Download Script: Configure-DcAuditObjectaccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Object Access Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Object Access Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Object Access Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Object Access Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditObjectaccessStatus.ps1">Download Script: Get-DcAuditObjectaccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditObjectaccessStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Handle Manipulation
$RawOutput = auditpol.exe /get /subcategory:"Handle Manipulation" /r
if ($RawOutput -notmatch ",Handle Manipulation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Registry
$RawOutput = auditpol.exe /get /subcategory:"Registry" /r
if ($RawOutput -notmatch ",Registry,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: File Share
$RawOutput = auditpol.exe /get /subcategory:"File Share" /r
if ($RawOutput -notmatch ",File Share,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Detailed File Share
$RawOutput = auditpol.exe /get /subcategory:"Detailed File Share" /r
if ($RawOutput -notmatch ",Detailed File Share,.*,Failure") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Object Access Events
$RawOutput = auditpol.exe /get /subcategory:"Other Object Access Events" /r
if ($RawOutput -notmatch ",Other Object Access Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Object Access Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Object Access Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Object Access Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Object Access Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2142" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-143" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-143] Audit Policy: Policy Change Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-policy-change.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing policy changes tracks attempts to modify authorization policies, auditing configuration changes, or firewall rule alterations to hide adversarial tracks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authentication Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authorization Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>MPSSVC Rule-Level Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Policy Change Events</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditPolicychange.ps1">Download Script: Configure-DcAuditPolicychange.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditPolicychangeStatus.ps1">Download Script: Get-DcAuditPolicychangeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditPolicychangeStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Policy Change" /r
if ($RawOutput -notmatch ",Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authentication Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authentication Policy Change" /r
if ($RawOutput -notmatch ",Authentication Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authorization Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authorization Policy Change" /r
if ($RawOutput -notmatch ",Authorization Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: MPSSVC Rule-Level Policy Change
$RawOutput = auditpol.exe /get /subcategory:"MPSSVC Rule-Level Policy Change" /r
if ($RawOutput -notmatch ",MPSSVC Rule-Level Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Policy Change Events
$RawOutput = auditpol.exe /get /subcategory:"Other Policy Change Events" /r
if ($RawOutput -notmatch ",Other Policy Change Events,.*,Failure") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2143" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-144" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-144] Audit Policy: Privilege Use Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-privilege-use.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing sensitive privilege use logs attempts by processes or users to exercise rights like ActAsPartOfTypeOperatingSystem or LoadDrivers, identifying potential privilege escalations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Sensitive Privilege Use</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditPrivilegeuse.ps1">Download Script: Configure-DcAuditPrivilegeuse.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditPrivilegeuseStatus.ps1">Download Script: Get-DcAuditPrivilegeuseStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditPrivilegeuseStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Sensitive Privilege Use
$RawOutput = auditpol.exe /get /subcategory:"Sensitive Privilege Use" /r
if ($RawOutput -notmatch ",Sensitive Privilege Use,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2144" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-145" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-145] Audit Policy: System Events Auditing on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/audit-policy/configure-dc-audit-system-events.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing system security extensions, integrity violations, and driver arrivals monitors boot health and tampering of host security services.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>IPsec Driver</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other System Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security State Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security System Extension</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>System Integrity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DcAuditSystemevents.ps1">Download Script: Configure-DcAuditSystemevents.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DcAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: IPsec Driver
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"IPsec Driver`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory IPsec Driver to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory IPsec Driver. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DcAuditSystemeventsStatus.ps1">Download Script: Get-DcAuditSystemeventsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DcAuditSystemeventsStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: IPsec Driver
$RawOutput = auditpol.exe /get /subcategory:"IPsec Driver" /r
if ($RawOutput -notmatch ",IPsec Driver,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other System Events
$RawOutput = auditpol.exe /get /subcategory:"Other System Events" /r
if ($RawOutput -notmatch ",Other System Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security State Change
$RawOutput = auditpol.exe /get /subcategory:"Security State Change" /r
if ($RawOutput -notmatch ",Security State Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security System Extension
$RawOutput = auditpol.exe /get /subcategory:"Security System Extension" /r
if ($RawOutput -notmatch ",Security System Extension,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: System Integrity
$RawOutput = auditpol.exe /get /subcategory:"System Integrity" /r
if ($RawOutput -notmatch ",System Integrity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DcAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: IPsec Driver
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"IPsec Driver`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory IPsec Driver to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory IPsec Driver. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2145" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_2__Domain_Controller_Hardening_Network_Parameter_Hardening">
      <title>Network Parameter Hardening</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-147" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-147] Configure TCP/IP KeepAliveTime on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/configure-tcpip-keepalivetime.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>KeepAliveTime</xhtml:code> parameter controls how often TCP attempts to verify that an idle connection is still intact by sending a keep-alive packet. If the remote system is still reachable and functioning, it acknowledges the keep-alive transmission.</xhtml:p>
          <xhtml:p>In Active Directory environments, Domain Controllers manage high volumes of concurrent Kerberos, LDAP, SMB, and RPC sessions with member servers and workstations. Configuring <xhtml:code>KeepAliveTime</xhtml:code> to 300,000 milliseconds (5 minutes) instead of the default 2 hours (7,200,000 ms) ensures orphaned or dead TCP connections from abruptly disconnected clients are detected and reclaimed promptly. This mitigates half-open connection accumulation and denial-of-service risks against server connection pools.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create or update the following Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>KeepAliveTime</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>300000</xhtml:code> (Decimal)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure <xhtml:code>KeepAliveTime</xhtml:code> on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-TcpipKeepAliveTime.ps1">Download Script: Configure-TcpipKeepAliveTime.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-TcpipKeepAliveTime.ps1
# Description: Configures TCP/IP KeepAliveTime parameter to 300000 ms (5 minutes) on Domain Controllers.

Write-Host "Configuring TCP/IP KeepAliveTime..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}

Set-ItemProperty -Path $TcpipParamsPath -Name "KeepAliveTime" -Value 300000 -Type DWord -ErrorAction Stop

Write-Host "TCP/IP KeepAliveTime configured successfully (300000 ms)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-TcpipKeepAliveTimeStatus.ps1">Download Script: Get-TcpipKeepAliveTimeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-TcpipKeepAliveTimeStatus.ps1
# Description: Audits registry configuration of TCP/IP KeepAliveTime on Domain Controllers.

Write-Host "--- Auditing TCP/IP KeepAliveTime ---" -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ExpectedValue = 300000

if (Test-Path -Path $TcpipParamsPath) {
    $Reg = Get-ItemProperty -Path $TcpipParamsPath -ErrorAction SilentlyContinue
    $CurrentValue = $Reg.KeepAliveTime

    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "    [+] KeepAliveTime: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "    [!] KeepAliveTime: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "    [!] TCP/IP Parameters Registry Path NOT FOUND" -ForegroundColor Red
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-TcpipKeepAliveTime.ps1
# Description: Configures TCP/IP KeepAliveTime parameter to 300000 ms (5 minutes) on Domain Controllers.

Write-Host "Configuring TCP/IP KeepAliveTime..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}

Set-ItemProperty -Path $TcpipParamsPath -Name "KeepAliveTime" -Value 300000 -Type DWord -ErrorAction Stop

Write-Host "TCP/IP KeepAliveTime configured successfully (300000 ms)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2147" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-148" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-148] Disable TCP/IP Router Discovery on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-tcpip-router-discovery.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Internet Router Discovery Protocol (IRDP, RFC 1256) enables IPv4 hosts to dynamically discover local default routers by listening for ICMP Router Advertisement packets or soliciting them via ICMP Router Solicitation messages.</xhtml:p>
          <xhtml:p>On Active Directory Domain Controllers, dynamic router discovery presents a severe attack surface: 1. <xhtml:strong>Rogue Gateway Redirection</xhtml:strong>: Attackers positioned on the local network segment can forge unauthenticated ICMP Router Advertisements to advertise a higher-priority default gateway address pointing to an attacker-controlled host. 2. <xhtml:strong>Man-in-the-Middle (MitM)</xhtml:strong>: Coercing the Domain Controller to route outbound network traffic through a rogue router allows attackers to intercept, inspect, or modify sensitive replication, Kerberos, LDAP, and DNS communication.</xhtml:p>
          <xhtml:p>Domain Controllers must operate exclusively with statically assigned or enterprise DHCP-reserved gateway addresses. Setting <xhtml:code>PerformRouterDiscovery</xhtml:code> to <xhtml:code>0</xhtml:code> explicitly disables IRDP processing.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create or update the following Registry Preference (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>PerformRouterDiscovery</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable router discovery on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableTcpipRouterDiscovery.ps1">Download Script: Configure-DisableTcpipRouterDiscovery.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableTcpipRouterDiscovery.ps1
# Description: Disables IRDP (PerformRouterDiscovery) on Domain Controllers.

Write-Host "Disabling TCP/IP Router Discovery..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}

Set-ItemProperty -Path $TcpipParamsPath -Name "PerformRouterDiscovery" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "TCP/IP Router Discovery disabled successfully (PerformRouterDiscovery = 0)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-TcpipRouterDiscoveryStatus.ps1">Download Script: Get-TcpipRouterDiscoveryStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-TcpipRouterDiscoveryStatus.ps1
# Description: Audits registry configuration of PerformRouterDiscovery on Domain Controllers.

Write-Host "--- Auditing TCP/IP Router Discovery Status ---" -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ExpectedValue = 0

if (Test-Path -Path $TcpipParamsPath) {
    $Reg = Get-ItemProperty -Path $TcpipParamsPath -ErrorAction SilentlyContinue
    $CurrentValue = $Reg.PerformRouterDiscovery

    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "    [+] PerformRouterDiscovery: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "    [!] PerformRouterDiscovery: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "    [!] TCP/IP Parameters Registry Path NOT FOUND" -ForegroundColor Red
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableTcpipRouterDiscovery.ps1
# Description: Disables IRDP (PerformRouterDiscovery) on Domain Controllers.

Write-Host "Disabling TCP/IP Router Discovery..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}

Set-ItemProperty -Path $TcpipParamsPath -Name "PerformRouterDiscovery" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "TCP/IP Router Discovery disabled successfully (PerformRouterDiscovery = 0)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2148" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-149" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-149] Configure TCP Max Data Retransmissions on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/configure-tcpip-max-data-retransmissions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>TcpMaxDataRetransmissions</xhtml:code> parameter determines the number of times TCP will retransmit an individual data segment (non-connect segment) before aborting the connection. The retransmission timeout is doubled with each successive retransmission on a connection, backed off exponentially.</xhtml:p>
          <xhtml:p>By default, Windows configures <xhtml:code>TcpMaxDataRetransmissions</xhtml:code> to <xhtml:code>5</xhtml:code>, which causes the system to wait over 200 seconds before terminating an unresponsive connection. In an Active Directory environment: 1. <xhtml:strong>Resource Exhaustion Mitigation</xhtml:strong>: Restricting retransmissions to <xhtml:code>3</xhtml:code> causes stalled or unresponsive connections to be severed significantly faster, releasing kernel memory buffers, TCP control blocks (TCBs), and socket handles. 2. <xhtml:strong>Denial-of-Service Defense</xhtml:strong>: In scenarios involving connection drop attacks, network partitions, or resource starvation attempts, limiting TCP data retransmissions for both IPv4 and IPv6 prevents connection pool depletion on Domain Controllers.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create or update the following Registry Preferences (Right-click <xhtml:strong>Registry -&gt; New -&gt; Registry Item</xhtml:strong>):</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>IPv4 TCP Max Data Retransmissions</xhtml:em>*:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>TcpMaxDataRetransmissions</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>3</xhtml:code> (Decimal)</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>IPv6 TCP Max Data Retransmissions</xhtml:em>*:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value name</xhtml:em>*: <xhtml:code>TcpMaxDataRetransmissions</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value data</xhtml:em>*: <xhtml:code>3</xhtml:code> (Decimal)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure <xhtml:code>TcpMaxDataRetransmissions</xhtml:code> for IPv4 and IPv6 on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-TcpipMaxDataRetransmissions.ps1">Download Script: Configure-TcpipMaxDataRetransmissions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-TcpipMaxDataRetransmissions.ps1
# Description: Sets TcpMaxDataRetransmissions to 3 for IPv4 and IPv6 on Domain Controllers.

Write-Host "Configuring TCP Max Data Retransmissions (IPv4 and IPv6)..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $TcpipParamsPath -Name "TcpMaxDataRetransmissions" -Value 3 -Type DWord -ErrorAction Stop

$Tcpip6ParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
if (-not (Test-Path -Path $Tcpip6ParamsPath)) {
    New-Item -Path $Tcpip6ParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $Tcpip6ParamsPath -Name "TcpMaxDataRetransmissions" -Value 3 -Type DWord -ErrorAction Stop

Write-Host "TCP Max Data Retransmissions configured to 3 for IPv4 and IPv6." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-TcpipMaxDataRetransmissionsStatus.ps1">Download Script: Get-TcpipMaxDataRetransmissionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-TcpipMaxDataRetransmissionsStatus.ps1
# Description: Audits registry configuration of TcpMaxDataRetransmissions for IPv4 and IPv6 on Domain Controllers.

Write-Host "--- Auditing TCP Max Data Retransmissions Status ---" -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$Tcpip6ParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
$IsVulnerable = $false

if (Test-Path -Path $TcpipParamsPath) {
    $Reg4 = Get-ItemProperty -Path $TcpipParamsPath -ErrorAction SilentlyContinue
    $Val4 = $Reg4.TcpMaxDataRetransmissions
    if ($Val4 -eq 3) {
        Write-Host "    [+] IPv4 TcpMaxDataRetransmissions: $($Val4) (Expected: 3)" -ForegroundColor Green
    } else {
        Write-Host "    [!] IPv4 TcpMaxDataRetransmissions: $($Val4) (Expected: 3)" -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "    [!] IPv4 Parameters Registry Path NOT FOUND" -ForegroundColor Red
    $IsVulnerable = $true
}

if (Test-Path -Path $Tcpip6ParamsPath) {
    $Reg6 = Get-ItemProperty -Path $Tcpip6ParamsPath -ErrorAction SilentlyContinue
    $Val6 = $Reg6.TcpMaxDataRetransmissions
    if ($Val6 -eq 3) {
        Write-Host "    [+] IPv6 TcpMaxDataRetransmissions: $($Val6) (Expected: 3)" -ForegroundColor Green
    } else {
        Write-Host "    [!] IPv6 TcpMaxDataRetransmissions: $($Val6) (Expected: 3)" -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "    [!] IPv6 Parameters Registry Path NOT FOUND" -ForegroundColor Red
    $IsVulnerable = $true
}

if ($IsVulnerable) {
    exit 1
} else {
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-TcpipMaxDataRetransmissions.ps1
# Description: Sets TcpMaxDataRetransmissions to 3 for IPv4 and IPv6 on Domain Controllers.

Write-Host "Configuring TCP Max Data Retransmissions (IPv4 and IPv6)..." -ForegroundColor Cyan

$TcpipParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
if (-not (Test-Path -Path $TcpipParamsPath)) {
    New-Item -Path $TcpipParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $TcpipParamsPath -Name "TcpMaxDataRetransmissions" -Value 3 -Type DWord -ErrorAction Stop

$Tcpip6ParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
if (-not (Test-Path -Path $Tcpip6ParamsPath)) {
    New-Item -Path $Tcpip6ParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $Tcpip6ParamsPath -Name "TcpMaxDataRetransmissions" -Value 3 -Type DWord -ErrorAction Stop

Write-Host "TCP Max Data Retransmissions configured to 3 for IPv4 and IPv6." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2149" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-150" severity="high" weight="10.0" selected="false">
        <title>[REQ-DC-150] Disable Default IPv6 DNS Servers on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-ipv6-default-dns-servers.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>By default, the Windows DNS client may fall back to well-known default IPv6 DNS addresses (such as site-local or router-advertised dynamic addresses) if statically configured DNS servers fail to respond, or when processing IPv6 router advertisements (RAs) via DHCPv6 / SLAAC.</xhtml:p>
          <xhtml:p>In an Active Directory environment: 1. <xhtml:strong>MitM and Rogue IPv6 DNS Redirection</xhtml:strong>: Attackers on the local network segment utilize tools like <xhtml:code>mitm6</xhtml:code> to broadcast rogue IPv6 Router Advertisements and rogue DHCPv6 replies, assigning an attacker-controlled IPv6 DNS server to systems on the subnet. 2. <xhtml:strong>Credential Relay &amp; Authentication Coercion</xhtml:strong>: When a Domain Controller queries DNS through a rogue IPv6 DNS server, the attacker can spoof hostnames (such as internal WPAD, CRL endpoints, or management servers) to coerce LDAP/SMB/HTTP authentication and perform NTLM relay attacks.</xhtml:p>
          <xhtml:p>Enabling <xhtml:code>Turn off default IPv6 DNS Servers</xhtml:code> (<xhtml:code>DisableIPv6DefaultDnsServers = 1</xhtml:code>) ensures that the DNS Client service does not fall back to default or dynamically acquired IPv6 DNS server addresses, confining DNS resolution strictly to administratively approved directory DNS servers.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\DNS Client</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Turn off default IPv6 DNS Servers</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable default IPv6 DNS servers on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableIPv6DefaultDnsServers.ps1">Download Script: Configure-DisableIPv6DefaultDnsServers.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableIPv6DefaultDnsServers.ps1
# Description: Disables default IPv6 DNS servers in DNS Client policy on Domain Controllers.

Write-Host "Disabling default IPv6 DNS servers..." -ForegroundColor Cyan

$DnsClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
if (-not (Test-Path -Path $DnsClientPath)) {
    New-Item -Path $DnsClientPath -Force | Out-Null
}

Set-ItemProperty -Path $DnsClientPath -Name "DisableIPv6DefaultDnsServers" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Default IPv6 DNS servers disabled successfully (DisableIPv6DefaultDnsServers = 1)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-DisableIPv6DefaultDnsServersStatus.ps1">Download Script: Get-DisableIPv6DefaultDnsServersStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DisableIPv6DefaultDnsServersStatus.ps1
# Description: Audits registry configuration of DisableIPv6DefaultDnsServers on Domain Controllers.

Write-Host "--- Auditing DisableIPv6DefaultDnsServers Status ---" -ForegroundColor Cyan

$DnsClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
$ExpectedValue = 1

if (Test-Path -Path $DnsClientPath) {
    $Reg = Get-ItemProperty -Path $DnsClientPath -ErrorAction SilentlyContinue
    $CurrentValue = $Reg.DisableIPv6DefaultDnsServers

    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "    [+] DisableIPv6DefaultDnsServers: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "    [!] DisableIPv6DefaultDnsServers: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "    [!] DNS Client Registry Path NOT FOUND" -ForegroundColor Red
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableIPv6DefaultDnsServers.ps1
# Description: Disables default IPv6 DNS servers in DNS Client policy on Domain Controllers.

Write-Host "Disabling default IPv6 DNS servers..." -ForegroundColor Cyan

$DnsClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
if (-not (Test-Path -Path $DnsClientPath)) {
    New-Item -Path $DnsClientPath -Force | Out-Null
}

Set-ItemProperty -Path $DnsClientPath -Name "DisableIPv6DefaultDnsServers" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Default IPv6 DNS servers disabled successfully (DisableIPv6DefaultDnsServers = 1)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2150" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-151" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-151] Disable Link-Layer Topology Discovery Mapper I/O Driver on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-lltd-mapper-io-driver.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Link-Layer Topology Discovery (LLTD) Mapper I/O (LLTDIO) network protocol driver queries neighboring network hosts to discover physical network topology, bandwidth capabilities, and device characteristics for Windows network mapping tools.</xhtml:p>
          <xhtml:p>On Tier 0 Domain Controllers: 1. <xhtml:strong>Attack Surface Minimization</xhtml:strong>: Domain Controllers must not act as network mapping query clients or probe neighboring devices. Running network discovery protocol drivers in kernel space introduces unnecessary attack surface. 2. <xhtml:strong>Reconnaissance Suppression</xhtml:strong>: Prohibiting LLTDIO driver activity ensures that the Domain Controller cannot be utilized to perform unauthorized local link-layer discovery queries across adjoining subnets.</xhtml:p>
          <xhtml:p>Disabling the Mapper I/O driver (<xhtml:code>Turn on Mapper I/O (LLTDIO) driver -&gt; Disabled</xhtml:code>) sets the registry flags under <xhtml:code>HKLM\SOFTWARE\Policies\Microsoft\Windows\LLTD</xhtml:code> to <xhtml:code>0</xhtml:code>, ensuring the driver is completely disabled across domain, private, and public network profiles.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Link-Layer Topology Discovery</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Turn on Mapper I/O (LLTDIO) driver</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable the LLTD Mapper I/O driver on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableLltdMapperIoDriver.ps1">Download Script: Configure-DisableLltdMapperIoDriver.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableLltdMapperIoDriver.ps1
# Description: Disables the LLTD Mapper I/O (LLTDIO) driver policy on Domain Controllers.

Write-Host "Disabling LLTD Mapper I/O (LLTDIO) Driver..." -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
if (-not (Test-Path -Path $LltdPath)) {
    New-Item -Path $LltdPath -Force | Out-Null
}

Set-ItemProperty -Path $LltdPath -Name "AllowLLTDIOOnDomain" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "AllowLLTDIOOnPublicNet" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "EnableLLTDIO" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "ProhibitLLTDIOOnPrivateNet" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "LLTD Mapper I/O Driver disabled successfully." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-LltdMapperIoDriverStatus.ps1">Download Script: Get-LltdMapperIoDriverStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-LltdMapperIoDriverStatus.ps1
# Description: Audits registry configuration of LLTD Mapper I/O (LLTDIO) driver on Domain Controllers.

Write-Host "--- Auditing LLTD Mapper I/O Driver Status ---" -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
$Expected = @{
    "AllowLLTDIOOnDomain"        = 0
    "AllowLLTDIOOnPublicNet"     = 0
    "EnableLLTDIO"               = 0
    "ProhibitLLTDIOOnPrivateNet" = 0
}

$IsVulnerable = $false

if (Test-Path -Path $LltdPath) {
    $Reg = Get-ItemProperty -Path $LltdPath -ErrorAction SilentlyContinue
    foreach ($Key in $Expected.Keys) {
        $Val = $Reg.$Key
        $Exp = $Expected[$Key]
        if ($Val -eq $Exp) {
            Write-Host "    [+] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Green
        } else {
            Write-Host "    [!] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Red
            $IsVulnerable = $true
        }
    }
} else {
    Write-Host "    [!] LLTD Registry Path NOT FOUND" -ForegroundColor Red
    $IsVulnerable = $true
}

if ($IsVulnerable) {
    exit 1
} else {
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableLltdMapperIoDriver.ps1
# Description: Disables the LLTD Mapper I/O (LLTDIO) driver policy on Domain Controllers.

Write-Host "Disabling LLTD Mapper I/O (LLTDIO) Driver..." -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
if (-not (Test-Path -Path $LltdPath)) {
    New-Item -Path $LltdPath -Force | Out-Null
}

Set-ItemProperty -Path $LltdPath -Name "AllowLLTDIOOnDomain" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "AllowLLTDIOOnPublicNet" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "EnableLLTDIO" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "ProhibitLLTDIOOnPrivateNet" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "LLTD Mapper I/O Driver disabled successfully." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2151" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-152" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-152] Disable Link-Layer Topology Discovery Responder Driver on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-lltd-responder-driver.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Link-Layer Topology Discovery (LLTD) Responder (RSPNDR) network protocol driver listens for topology discovery requests from other computers on the local network and responds with device details, identity information, and link-layer capabilities.</xhtml:p>
          <xhtml:p>On Tier 0 Domain Controllers: 1. <xhtml:strong>Device Fingerprinting Prevention</xhtml:strong>: Enabling the Responder driver allows any workstation or rogue host on the local physical segment to discover the Domain Controller, map its MAC address, determine link characteristics, and identify its role via LLTD probe packets. 2. <xhtml:strong>Network Protocol Stack Reduction</xhtml:strong>: Running link-layer responders in the kernel networking stack exposes the server to packet-handling vulnerabilities and potential broadcast flooding attacks.</xhtml:p>
          <xhtml:p>Disabling the Responder driver (<xhtml:code>Turn on Responder (RSPNDR) driver -&gt; Disabled</xhtml:code>) ensures that the Domain Controller never advertises itself or responds to link-layer topological queries.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Link-Layer Topology Discovery</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Turn on Responder (RSPNDR) driver</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable the LLTD Responder driver on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableLltdResponderDriver.ps1">Download Script: Configure-DisableLltdResponderDriver.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableLltdResponderDriver.ps1
# Description: Disables the LLTD Responder (RSPNDR) driver policy on Domain Controllers.

Write-Host "Disabling LLTD Responder (RSPNDR) Driver..." -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
if (-not (Test-Path -Path $LltdPath)) {
    New-Item -Path $LltdPath -Force | Out-Null
}

Set-ItemProperty -Path $LltdPath -Name "AllowRspndrOnDomain" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "AllowRspndrOnPublicNet" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "EnableRspndr" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "ProhibitRspndrOnPrivateNet" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "LLTD Responder Driver disabled successfully." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-LltdResponderDriverStatus.ps1">Download Script: Get-LltdResponderDriverStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-LltdResponderDriverStatus.ps1
# Description: Audits registry configuration of LLTD Responder (RSPNDR) driver on Domain Controllers.

Write-Host "--- Auditing LLTD Responder Driver Status ---" -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
$Expected = @{
    "AllowRspndrOnDomain"        = 0
    "AllowRspndrOnPublicNet"     = 0
    "EnableRspndr"               = 0
    "ProhibitRspndrOnPrivateNet" = 0
}

$IsVulnerable = $false

if (Test-Path -Path $LltdPath) {
    $Reg = Get-ItemProperty -Path $LltdPath -ErrorAction SilentlyContinue
    foreach ($Key in $Expected.Keys) {
        $Val = $Reg.$Key
        $Exp = $Expected[$Key]
        if ($Val -eq $Exp) {
            Write-Host "    [+] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Green
        } else {
            Write-Host "    [!] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Red
            $IsVulnerable = $true
        }
    }
} else {
    Write-Host "    [!] LLTD Registry Path NOT FOUND" -ForegroundColor Red
    $IsVulnerable = $true
}

if ($IsVulnerable) {
    exit 1
} else {
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableLltdResponderDriver.ps1
# Description: Disables the LLTD Responder (RSPNDR) driver policy on Domain Controllers.

Write-Host "Disabling LLTD Responder (RSPNDR) Driver..." -ForegroundColor Cyan

$LltdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LLTD"
if (-not (Test-Path -Path $LltdPath)) {
    New-Item -Path $LltdPath -Force | Out-Null
}

Set-ItemProperty -Path $LltdPath -Name "AllowRspndrOnDomain" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "AllowRspndrOnPublicNet" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "EnableRspndr" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $LltdPath -Name "ProhibitRspndrOnPrivateNet" -Value 0 -Type DWord -ErrorAction Stop

Write-Host "LLTD Responder Driver disabled successfully." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2152" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-153" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-153] Disable Microsoft Peer-to-Peer Networking Services on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-peernet.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Microsoft Peer-to-Peer Networking Services comprise technologies such as the Peer Name Resolution Protocol (PNRP), Peer Graphing, and Grouping. These services allow distributed applications and workstations to locate each other, publish identities in peer clouds, and exchange data directly without centralized servers.</xhtml:p>
          <xhtml:p>On Active Directory Domain Controllers: 1. <xhtml:strong>Inappropriate Technology on Tier 0</xhtml:strong>: Domain Controllers are centralized identity authorities designed for hierarchical client-server communication. Peer-to-peer mechanisms are completely antithetical to Tier 0 security isolation. 2. <xhtml:strong>Untracked Communication Channels</xhtml:strong>: PNRP and peer networks establish autonomous, unmanaged communication channels that bypass traditional network inspection and create covert data exchange surfaces. 3. <xhtml:strong>Attack Surface Reduction</xhtml:strong>: Disabling Peernet services (<xhtml:code>Disabled = 1</xhtml:code>) eliminates the PNRP protocol stack and shuts down peer mesh discovery ports on Domain Controllers.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Microsoft Peer-to-Peer Networking Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Turn off Microsoft Peer-to-Peer Networking Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Microsoft Peer-to-Peer Networking Services on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePeernet.ps1">Download Script: Configure-DisablePeernet.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePeernet.ps1
# Description: Disables Microsoft Peer-to-Peer Networking Services policy on Domain Controllers.

Write-Host "Disabling Microsoft Peer-to-Peer Networking Services..." -ForegroundColor Cyan

$PeernetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Peernet"
if (-not (Test-Path -Path $PeernetPath)) {
    New-Item -Path $PeernetPath -Force | Out-Null
}

Set-ItemProperty -Path $PeernetPath -Name "Disabled" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Microsoft Peer-to-Peer Networking Services disabled successfully (Disabled = 1)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PeernetStatus.ps1">Download Script: Get-PeernetStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PeernetStatus.ps1
# Description: Audits registry configuration of Microsoft Peer-to-Peer Networking Services on Domain Controllers.

Write-Host "--- Auditing Microsoft Peer-to-Peer Networking Services Status ---" -ForegroundColor Cyan

$PeernetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Peernet"
$ExpectedValue = 1

if (Test-Path -Path $PeernetPath) {
    $Reg = Get-ItemProperty -Path $PeernetPath -ErrorAction SilentlyContinue
    $CurrentValue = $Reg.Disabled

    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "    [+] Peernet Disabled: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "    [!] Peernet Disabled: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "    [!] Peernet Registry Path NOT FOUND" -ForegroundColor Red
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePeernet.ps1
# Description: Disables Microsoft Peer-to-Peer Networking Services policy on Domain Controllers.

Write-Host "Disabling Microsoft Peer-to-Peer Networking Services..." -ForegroundColor Cyan

$PeernetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Peernet"
if (-not (Test-Path -Path $PeernetPath)) {
    New-Item -Path $PeernetPath -Force | Out-Null
}

Set-ItemProperty -Path $PeernetPath -Name "Disabled" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Microsoft Peer-to-Peer Networking Services disabled successfully (Disabled = 1)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2153" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-154" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-154] Disable Windows Connect Now Wireless Settings Configuration on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/disable-wcn-wireless-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows Connect Now (WCN) provides mechanisms for wireless network configuration using Wi-Fi Protected Setup (WPS) protocols across various discovery media, including UPnP (Universal Plug and Play), In-Band 802.11, USB flash drives (FlashConfig), and Windows Portable Devices (WPD).</xhtml:p>
          <xhtml:p>On Active Directory Domain Controllers: 1. <xhtml:strong>Tier 0 Dedicated Wired Infrastructure</xhtml:strong>: Domain Controllers must run on dedicated, physical wired server backbones within physically secured datacenter segments. Wireless configuration mechanisms have no legitimate place on these machines. 2. <xhtml:strong>UPnP and Wireless Exploitation</xhtml:strong>: UPnP registrars and in-band 802.11 discovery listening components can introduce local broadcast vulnerabilities, unauthenticated device registration attacks, or credential leakage over broadcast media. 3. <xhtml:strong>Attack Surface Elimination</xhtml:strong>: Setting <xhtml:code>Configuration of wireless settings using Windows Connect Now</xhtml:code> to <xhtml:code>Disabled</xhtml:code> ensures that all WCN registrars (UPnP, In-Band 802.11, FlashConfig, WPD) are explicitly turned off.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Windows Connect Now</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Configuration of wireless settings using Windows Connect Now</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable WCN wireless settings configuration registrars on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWcnWirelessConfig.ps1">Download Script: Configure-DisableWcnWirelessConfig.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWcnWirelessConfig.ps1
# Description: Disables Windows Connect Now wireless settings configuration registrars on Domain Controllers.

Write-Host "Disabling Windows Connect Now Wireless Settings Configuration..." -ForegroundColor Cyan

$WcnRegsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars"
if (-not (Test-Path -Path $WcnRegsPath)) {
    New-Item -Path $WcnRegsPath -Force | Out-Null
}

Set-ItemProperty -Path $WcnRegsPath -Name "EnableRegistrars" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableUPnPRegistrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableInBand802DOT11Registrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableFlashConfigRegistrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableWPDRegistrar" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Windows Connect Now Wireless Settings Configuration disabled successfully." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WcnWirelessConfigStatus.ps1">Download Script: Get-WcnWirelessConfigStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WcnWirelessConfigStatus.ps1
# Description: Audits registry configuration of Windows Connect Now registrars on Domain Controllers.

Write-Host "--- Auditing Windows Connect Now Wireless Settings Configuration Status ---" -ForegroundColor Cyan

$WcnRegsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars"
$Expected = @{
    "EnableRegistrars"               = 0
    "DisableUPnPRegistrar"           = 1
    "DisableInBand802DOT11Registrar" = 1
    "DisableFlashConfigRegistrar"    = 1
    "DisableWPDRegistrar"            = 1
}

$IsVulnerable = $false

if (Test-Path -Path $WcnRegsPath) {
    $Reg = Get-ItemProperty -Path $WcnRegsPath -ErrorAction SilentlyContinue
    foreach ($Key in $Expected.Keys) {
        $Val = $Reg.$Key
        $Exp = $Expected[$Key]
        if ($Val -eq $Exp) {
            Write-Host "    [+] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Green
        } else {
            Write-Host "    [!] $($Key): $($Val) (Expected: $($Exp))" -ForegroundColor Red
            $IsVulnerable = $true
        }
    }
} else {
    Write-Host "    [!] WCN Registrars Registry Path NOT FOUND" -ForegroundColor Red
    $IsVulnerable = $true
}

if ($IsVulnerable) {
    exit 1
} else {
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWcnWirelessConfig.ps1
# Description: Disables Windows Connect Now wireless settings configuration registrars on Domain Controllers.

Write-Host "Disabling Windows Connect Now Wireless Settings Configuration..." -ForegroundColor Cyan

$WcnRegsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars"
if (-not (Test-Path -Path $WcnRegsPath)) {
    New-Item -Path $WcnRegsPath -Force | Out-Null
}

Set-ItemProperty -Path $WcnRegsPath -Name "EnableRegistrars" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableUPnPRegistrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableInBand802DOT11Registrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableFlashConfigRegistrar" -Value 1 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $WcnRegsPath -Name "DisableWPDRegistrar" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Windows Connect Now Wireless Settings Configuration disabled successfully." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2154" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-DC-155" severity="medium" weight="10.0" selected="false">
        <title>[REQ-DC-155] Prohibit Access to Windows Connect Now Wizards on Domain Controllers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>02-domain-controllers/network/prohibit-wcn-wizards.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Connect Now (WCN) wizards guide users through configuring a wireless router or access point and saving network configuration settings to USB flash memory or broadcasting them via Wi-Fi.</xhtml:p>
          <xhtml:p>On Tier 0 Domain Controllers: 1. <xhtml:strong>Administrative Interface Lockdown</xhtml:strong>: Interactive administrative sessions on Domain Controllers must never expose consumer wireless or hardware configuration wizards that could be inadvertently or maliciously invoked. 2. <xhtml:strong>Prevent Unauthorized Configuration Storage</xhtml:strong>: WCN wizards allow exporting wireless network keys and connection settings to removable storage or across the network. Prohibiting access to the WCN wizards (<xhtml:code>DisableWcnUi = 1</xhtml:code>) ensures the GUI wizard interface cannot be launched.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the GPO linked to the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Windows Connect Now</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Prohibit access of the Windows Connect Now wizards</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>State</xhtml:em>
              <xhtml:em>: </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to prohibit access to WCN wizards on the Domain Controller.</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-ProhibitWcnWizards.ps1">Download Script: Configure-ProhibitWcnWizards.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-ProhibitWcnWizards.ps1
# Description: Prohibits access to Windows Connect Now wizards on Domain Controllers.

Write-Host "Prohibiting access to Windows Connect Now wizards..." -ForegroundColor Cyan

$WcnUiPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\UI"
if (-not (Test-Path -Path $WcnUiPath)) {
    New-Item -Path $WcnUiPath -Force | Out-Null
}

Set-ItemProperty -Path $WcnUiPath -Name "DisableWcnUi" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Windows Connect Now wizards prohibited successfully (DisableWcnUi = 1)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the setting has been applied:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-ProhibitWcnWizardsStatus.ps1">Download Script: Get-ProhibitWcnWizardsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-ProhibitWcnWizardsStatus.ps1
# Description: Audits registry configuration of DisableWcnUi on Domain Controllers.

Write-Host "--- Auditing DisableWcnUi Status ---" -ForegroundColor Cyan

$WcnUiPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\UI"
$ExpectedValue = 1

if (Test-Path -Path $WcnUiPath) {
    $Reg = Get-ItemProperty -Path $WcnUiPath -ErrorAction SilentlyContinue
    $CurrentValue = $Reg.DisableWcnUi

    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "    [+] DisableWcnUi: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "    [!] DisableWcnUi: $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "    [!] WCN UI Registry Path NOT FOUND" -ForegroundColor Red
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-ProhibitWcnWizards.ps1
# Description: Prohibits access to Windows Connect Now wizards on Domain Controllers.

Write-Host "Prohibiting access to Windows Connect Now wizards..." -ForegroundColor Cyan

$WcnUiPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WCN\UI"
if (-not (Test-Path -Path $WcnUiPath)) {
    New-Item -Path $WcnUiPath -Force | Out-Null
}

Set-ItemProperty -Path $WcnUiPath -Name "DisableWcnUi" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "Windows Connect Now wizards prohibited successfully (DisableWcnUi = 1)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:2155" />
        </check>
      </Rule>
    </Group>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_3__Identities___Services_Hardening">
    <title>Module 3: Identities &amp; Services Hardening</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-001] Enforce Fine-Grained Password Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/enforce-fgpp.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory default domain password policies apply globally to all user accounts. These global policies are often configured with lower complexity and length requirements to avoid overwhelming standard users. However, such settings are inadequate for highly privileged accounts (Tier 0 and Tier 1 administrators), which are primary targets for credential stuffing, brute-force, and offline cracking attacks.</xhtml:p>
        <xhtml:p>Enforcing Fine-Grained Password Policies (FGPP) via Password Settings Objects (PSOs) allows administrators to apply distinct, highly restrictive password and account lockout policies to specific users or groups. By mandating longer password lengths and stricter lockout thresholds for privileged identities, the domain's defense-in-depth posture is significantly bolstered without affecting standard users.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Center (ADAC) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>) on a Domain Controller or management server.</xhtml:li>
          <xhtml:li>Switch to the Tree View, select your domain, and navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>System\Password Settings Container</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click the <xhtml:strong>Password Settings Container</xhtml:strong>, select <xhtml:strong>New</xhtml:strong>, and then click <xhtml:strong>Password Settings</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the Password Settings Object (PSO):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>Tier0-Admin-PSO</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Precedence</xhtml:em>*: <xhtml:code>10</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce minimum password length</xhtml:em>*: <xhtml:code>20</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Password must meet complexity requirements</xhtml:em>*: Checked</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce password history</xhtml:em>*: <xhtml:code>24</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Store password using reversible encryption</xhtml:em>*: Unchecked</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Number of failed logon attempts allowed (lockout threshold)</xhtml:em>*: <xhtml:code>5</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Reset failed logon attempts count after</xhtml:em>*: <xhtml:code>30 minutes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account lockout duration</xhtml:em>*: <xhtml:code>30 minutes</xhtml:code>
          </xhtml:li>
          <xhtml:li>Under <xhtml:strong>Directly Applies To</xhtml:strong>, click <xhtml:strong>Add</xhtml:strong> and select the security group containing your Tier 0 and Tier 1 administrators (e.g., <xhtml:code>Grp_Tier0_Admins</xhtml:code>).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save and apply the PSO.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to create and apply the Fine-Grained Password Policy using PowerShell.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-AdminPasswordPolicy.ps1">Download Script: Set-AdminPasswordPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-AdminPasswordPolicy.ps1
# Description: Creates a secure Fine-Grained Password Policy for administrative accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce Fine-Grained Password Policies..." -ForegroundColor Cyan

$AdminPSOName = "Tier0-Admin-PSO"
$ExistingPSO = Get-ADFineGrainedPasswordPolicy -Filter "Name -eq '$AdminPSOName'"

if (-not $ExistingPSO) {
    # Create the Fine-Grained Password Policy (PSO)
    New-ADFineGrainedPasswordPolicy -Name $AdminPSOName `
        -Precedence 10 `
        -ComplexityEnabled $true `
        -MinPasswordLength 20 `
        -PasswordHistoryCount 24 `
        -ReversibleEncryptionEnabled $false `
        -LockoutDuration "00:30:00" `
        -LockoutObservationWindow "00:30:00" `
        -LockoutThreshold 5 `
        -MinPasswordAge "1.00:00:00" `
        -MaxPasswordAge "60.00:00:00"
        
    Write-Host "PSO '$AdminPSOName' created successfully." -ForegroundColor Green
} else {
    Write-Host "PSO '$AdminPSOName' already exists." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the applied Fine-Grained Password Policies:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AdminPasswordPolicyStatus.ps1">Download Script: Get-AdminPasswordPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AdminPasswordPolicyStatus.ps1
# Description: Audits Fine-Grained Password Policies in the Active Directory domain.

Import-Module ActiveDirectory

Write-Host "--- Auditing Fine-Grained Password Policies ---" -ForegroundColor Cyan

$psoList = Get-ADFineGrainedPasswordPolicy -Filter *

if ($psoList) {
    foreach ($pso in $psoList) {
        Write-Host "[+] PSO Name: $($pso.Name)" -ForegroundColor Green
        Write-Host "    - Precedence: $($pso.Precedence)" -ForegroundColor White
        Write-Host "    - MinPasswordLength: $($pso.MinPasswordLength)" -ForegroundColor White
        Write-Host "    - LockoutThreshold: $($pso.LockoutThreshold)" -ForegroundColor White
        Write-Host "    - LockoutDuration: $($pso.LockoutDuration)" -ForegroundColor White
    }
} else {
    Write-Host "[-] No Fine-Grained Password Policies found in the domain." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-AdminPasswordPolicy.ps1
# Description: Creates a secure Fine-Grained Password Policy for administrative accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce Fine-Grained Password Policies..." -ForegroundColor Cyan

$AdminPSOName = "Tier0-Admin-PSO"
$ExistingPSO = Get-ADFineGrainedPasswordPolicy -Filter "Name -eq '$AdminPSOName'"

if (-not $ExistingPSO) {
    # Create the Fine-Grained Password Policy (PSO)
    New-ADFineGrainedPasswordPolicy -Name $AdminPSOName `
        -Precedence 10 `
        -ComplexityEnabled $true `
        -MinPasswordLength 20 `
        -PasswordHistoryCount 24 `
        -ReversibleEncryptionEnabled $false `
        -LockoutDuration "00:30:00" `
        -LockoutObservationWindow "00:30:00" `
        -LockoutThreshold 5 `
        -MinPasswordAge "1.00:00:00" `
        -MaxPasswordAge "60.00:00:00"
        
    Write-Host "PSO '$AdminPSOName' created successfully." -ForegroundColor Green
} else {
    Write-Host "PSO '$AdminPSOName' already exists." -ForegroundColor Yellow
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-002] Enable Local Administrator Password Solution (LAPS)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Member Servers, Tier 2 Clients, Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Modern Windows LAPS</xhtml:strong>: Windows Server 2019/2022/2025 (with April 11, 2023 cumulative update or later), Windows 10/11 (with April 11, 2023 cumulative update or later)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Legacy Microsoft LAPS</xhtml:strong>: Windows Server 2016 (and older), Windows 7/8/8.1, Windows Server 2008 R2/2012/2012 R2</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/enable-laps.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In standard Active Directory setups, local administrator accounts on member servers and client workstations often share the same password. If a single machine is compromised and the local administrator password hash is extracted (e.g., from LSASS memory or SAM database), attackers can leverage Pass-the-Hash (PtH) techniques to log on to other domain machines laterally.</xhtml:p>
        <xhtml:p>Implementing the Local Administrator Password Solution (LAPS) completely mitigates this lateral movement vector by automatically generating a unique, complex password for the specified local administrator account on each machine. These passwords are changed periodically and stored securely in a confidential attribute (<xhtml:code>msLAPS-Password</xhtml:code> or <xhtml:code>ms-Mcs-AdmPwd</xhtml:code>) on the computer's Active Directory object. Read access is restricted to authorized administrative groups.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_MemberServers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\LAPS</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure password backup directory</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>*: Set backup directory to <xhtml:code>Active Directory</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Do not allow password expiration time longer than required by policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Enable password encryption</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Password Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>*: Set complexity to <xhtml:code>Large letters + small letters + numbers + special characters</xhtml:code>, length to <xhtml:code>20</xhtml:code>, and age to <xhtml:code>30</xhtml:code> days.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Post-authentication actions</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>*: Set Grace period (hours) to <xhtml:code>8</xhtml:code>, Actions to <xhtml:code>Reset the password and logoff the managed account</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Enable local admin password management</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the Organizational Units (OUs) containing member servers and client workstations.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for testing or standalone systems) or if the control is not manageable via standard GPO GUI interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-LAPS.ps1">Download Script: Configure-LAPS.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-LAPS.ps1
# Description: Configures Windows LAPS parameters in the registry.

Write-Host "Applying hardening requirement: Enable Local Administrator Password Solution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# Enable LAPS management
Set-ItemProperty -Path $RegPath -Name "EnableLAPS" -Value 1 -Type DWord
# 2 = Backup to Active Directory
Set-ItemProperty -Path $RegPath -Name "BackupDirectory" -Value 2 -Type DWord
# 1 = Do not allow password expiration time longer than required by policy
Set-ItemProperty -Path $RegPath -Name "PasswordExpirationProtectionEnabled" -Value 1 -Type DWord
# 1 = Enable password encryption
Set-ItemProperty -Path $RegPath -Name "ADPasswordEncryptionEnabled" -Value 1 -Type DWord
# 4 = Letters + numbers + special characters
Set-ItemProperty -Path $RegPath -Name "PasswordComplexity" -Value 4 -Type DWord
Set-ItemProperty -Path $RegPath -Name "PasswordLength" -Value 20 -Type DWord
Set-ItemProperty -Path $RegPath -Name "PasswordAgeDays" -Value 30 -Type DWord
# 8 = Grace period of 8 hours
Set-ItemProperty -Path $RegPath -Name "PostAuthenticationResetDelay" -Value 8 -Type DWord
# 3 = Reset the password and logoff the managed account
Set-ItemProperty -Path $RegPath -Name "PostAuthenticationActions" -Value 3 -Type DWord

Write-Host "Windows LAPS configuration registry settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-LAPS.ps1
# Description: Configures Windows LAPS parameters in the registry.

Write-Host "Applying hardening requirement: Enable Local Administrator Password Solution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# Enable LAPS management
Set-ItemProperty -Path $RegPath -Name "EnableLAPS" -Value 1 -Type DWord
# 2 = Backup to Active Directory
Set-ItemProperty -Path $RegPath -Name "BackupDirectory" -Value 2 -Type DWord
# 1 = Do not allow password expiration time longer than required by policy
Set-ItemProperty -Path $RegPath -Name "PasswordExpirationProtectionEnabled" -Value 1 -Type DWord
# 1 = Enable password encryption
Set-ItemProperty -Path $RegPath -Name "ADPasswordEncryptionEnabled" -Value 1 -Type DWord
# 4 = Letters + numbers + special characters
Set-ItemProperty -Path $RegPath -Name "PasswordComplexity" -Value 4 -Type DWord
Set-ItemProperty -Path $RegPath -Name "PasswordLength" -Value 20 -Type DWord
Set-ItemProperty -Path $RegPath -Name "PasswordAgeDays" -Value 30 -Type DWord
# 8 = Grace period of 8 hours
Set-ItemProperty -Path $RegPath -Name "PostAuthenticationResetDelay" -Value 8 -Type DWord
# 3 = Reset the password and logoff the managed account
Set-ItemProperty -Path $RegPath -Name "PostAuthenticationActions" -Value 3 -Type DWord

Write-Host "Windows LAPS configuration registry settings applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-003] Implement Group Managed Service Accounts (gMSA)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/harden-service-accounts.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Traditional service accounts in Active Directory are standard user accounts with static, often long-lived passwords. Because service passwords are rarely rotated, they are prime targets for offline brute-force attacks known as <xhtml:strong>Kerberoasting</xhtml:strong>. An attacker with domain access can request a Kerberos service ticket (TGS) for any account with a Service Principal Name (SPN) and attempt to crack the password hash offline.</xhtml:p>
        <xhtml:p>Group Managed Service Accounts (gMSAs) address this risk by delegating password management to the operating system and Domain Controllers. Windows automatically generates a complex 120-character password for each gMSA and rotates it every 30 days. Additionally, gMSAs cannot be used for interactive logons, preventing administrative session hijacking or remote administrative access via service accounts.</xhtml:p>
        <xhtml:p>However, gMSAs introduce specific security boundaries that must be strictly enforced: 1. <xhtml:strong>Password Retrieval Delegation (GMSA Password Access)</xhtml:strong>: The attribute <xhtml:code>msDS-GroupMSAMembership</xhtml:code> (<xhtml:code>PrincipalsAllowedToRetrieveManagedPassword</xhtml:code>) defines which security principals can query Active Directory to retrieve the clear-text gMSA password. If human user accounts or groups containing human users are added to this attribute, any compromise of those user credentials allows an attacker to fetch the clear-text password blob and convert it to an NT hash. 2. <xhtml:strong>Credential Dumping from memory (LSASS ekeys)</xhtml:strong>: While LSASS does not cache the clear-text password of a gMSA under standard <xhtml:code>sekurlsa::logonpasswords</xhtml:code> dumps, the active Kerberos keys (NT hash, AES-128/256 keys) are stored in memory on the host computer running the service. An attacker with administrative/SYSTEM access to the host server can extract these keys using Mimikatz <xhtml:code>sekurlsa::ekeys</xhtml:code> and use them for pass-the-hash (PTH) or pass-the-ticket (PTT) attacks. 3. <xhtml:strong>Tier Alignment (Tier-Matching)</xhtml:strong>: Because compromising the host server hosting a gMSA compromises the gMSA itself, and retrieving the gMSA password grants full control over its permissions, hosts running gMSAs must be secured to the same level (Tier) as the privileges granted to the gMSA. A Tier 0 gMSA must only run on Tier 0 systems (Domain Controllers or Tier 0 Admin Hosts), and only Tier 0 computer accounts/groups must be allowed to retrieve its password.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Management Console Configuration (Preferred)</xhtml:h3>
        <xhtml:p>gMSAs are primarily created and managed using administrative consoles or PowerShell.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Verify the presence of the default <xhtml:strong>Managed Service Accounts</xhtml:strong> container.</xhtml:li>
          <xhtml:li>Because gMSA creation requires AD schema and principal mapping, PowerShell is the primary method used to initialize and link the account to the host server. Follow the steps in Option B.</xhtml:li>
          <xhtml:li>Once created, configure the target service (e.g., in Services Console <xhtml:code>services.msc</xhtml:code>):</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set </xhtml:em>
            <xhtml:em>Log On As</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>This account</xhtml:em>*.</xhtml:li>
          <xhtml:li>* Enter the name of the gMSA with a trailing dollar sign (e.g., <xhtml:code>domain\gmsa-sqlservice$</xhtml:code>).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Clear the Password fields and click </xhtml:em>
            <xhtml:em>OK</xhtml:em>*.</xhtml:li>
          <xhtml:li>* Restart the service.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use the following PowerShell script to initialize the KDS root key (if not already done) and create a gMSA.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-gMSAServiceAccount.ps1">Download Script: Set-gMSAServiceAccount.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-gMSAServiceAccount.ps1
# Description: Generates the KDS root key and registers a new gMSA.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Implement Group Managed Service Accounts..." -ForegroundColor Cyan

# 1. Initialize KDS Root Key (Required once in the forest)
# In standard setups, there is a 10-hour delay for propagation.
# -EffectiveImmediately is used for lab configurations.
try {
    Add-KdsRootKey -EffectiveImmediately -ErrorAction SilentlyContinue
    Write-Host "[+] KDS Root Key creation initiated/verified." -ForegroundColor Green
} catch {
    Write-Warning "Could not configure KDS Root Key. It may already exist."
}

# 2. Create the gMSA
$gMSAName = "gmsa-sqlservice"
$existingMSA = Get-ADServiceAccount -Filter "Name -eq '$gMSAName'"

if (-not $existingMSA) {
    # Specify the name, DNS, and which principals (member servers running the service) can retrieve the password.
    # CRITICAL: Do NOT allow user accounts or groups containing users (like Domain Admins or Schema Admins) 
    # to retrieve the password. Only allow the specific computer account(s) hosting the service.
    $targetHostComputer = "SQLServerHost$"
    
    New-ADServiceAccount -Name $gMSAName `
        -DNSHostName "$gMSAName.domain.local" `
        -ManagedPasswordIntervalInDays 30 `
        -PrincipalsAllowedToRetrieveManagedPassword $targetHostComputer
        
    Write-Host "[+] gMSA '$gMSAName' created successfully." -ForegroundColor Green
} else {
    Write-Host "[-] gMSA '$gMSAName' already exists." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit registered Managed Service Accounts:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-gMSAStatus.ps1">Download Script: Get-gMSAStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-gMSAStatus.ps1
# Description: Lists all registered gMSAs and audits password retrieval delegation permissions.

Import-Module ActiveDirectory

Write-Host "--- Auditing Group Managed Service Accounts ---" -ForegroundColor Cyan

$gMSAs = Get-ADServiceAccount -Filter * -Properties Name, DNSHostName, Enabled, PrincipalsAllowedToRetrieveManagedPassword

if ($gMSAs) {
    foreach ($sa in $gMSAs) {
        $nonCompliant = $false
        Write-Host "[*] gMSA Account: $($sa.Name)" -ForegroundColor White
        Write-Host "    - DNS Name: $($sa.DNSHostName)" -ForegroundColor White
        Write-Host "    - Enabled: $($sa.Enabled)" -ForegroundColor White
        
        $principals = $sa.PrincipalsAllowedToRetrieveManagedPassword
        if ($null -ne $principals) {
            Write-Host "    - Principals Allowed to Retrieve Password:" -ForegroundColor White
            foreach ($p in $principals) {
                # Get the AD Object to verify class and name
                $adObj = Get-ADObject -Identity $p.DistinguishedName -Properties ObjectClass, Name
                if ($null -ne $adObj) {
                    $objType = $adObj.ObjectClass
                    $name = $adObj.Name
                    
                    if ($objType -eq "user") {
                        Write-Host "      [-] WARNING: User account '$($name)' is explicitly allowed to retrieve password (HIGH RISK)" -ForegroundColor Red
                        $nonCompliant = $true
                    } elseif ($objType -eq "group") {
                        Write-Host "      [!] Group: '$($name)'" -ForegroundColor Yellow
                        
                        # Recursively resolve members to check for users
                        $members = Get-ADGroupMember -Identity $p.DistinguishedName -Recursive
                        $userMembers = $members | Where-Object { $_.objectClass -eq "user" }
                        
                        if ($userMembers) {
                            $userNames = @()
                            foreach ($user in $userMembers) {
                                $userNames += $user.Name
                            }
                            $usersList = $userNames -join ", "
                            Write-Host "        [-] WARNING: Group '$($name)' contains human user accounts: $($usersList) (HIGH RISK)" -ForegroundColor Red
                            $nonCompliant = $true
                        } else {
                            Write-Host "        [+] Group contains only computer/service accounts." -ForegroundColor Green
                        }
                    } else {
                        Write-Host "      [+] Computer/Host: '$($name)'" -ForegroundColor Green
                    }
                }
            }
        } else {
            Write-Host "    [-] WARNING: No principals allowed to retrieve password (gMSA will not function)." -ForegroundColor Yellow
            $nonCompliant = $true
        }
        
        if ($nonCompliant) {
            Write-Host "    [-] STATUS: NON-COMPLIANT (Insecure password retrieval delegation)" -ForegroundColor Red
        } else {
            Write-Host "    [+] STATUS: COMPLIANT" -ForegroundColor Green
        }
        Write-Host ""
    }
} else {
    Write-Host "[-] No Group Managed Service Accounts found in the Active Directory domain." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-gMSAServiceAccount.ps1
# Description: Generates the KDS root key and registers a new gMSA.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Implement Group Managed Service Accounts..." -ForegroundColor Cyan

# 1. Initialize KDS Root Key (Required once in the forest)
# In standard setups, there is a 10-hour delay for propagation.
# -EffectiveImmediately is used for lab configurations.
try {
    Add-KdsRootKey -EffectiveImmediately -ErrorAction SilentlyContinue
    Write-Host "[+] KDS Root Key creation initiated/verified." -ForegroundColor Green
} catch {
    Write-Warning "Could not configure KDS Root Key. It may already exist."
}

# 2. Create the gMSA
$gMSAName = "gmsa-sqlservice"
$existingMSA = Get-ADServiceAccount -Filter "Name -eq '$gMSAName'"

if (-not $existingMSA) {
    # Specify the name, DNS, and which principals (member servers running the service) can retrieve the password.
    # CRITICAL: Do NOT allow user accounts or groups containing users (like Domain Admins or Schema Admins) 
    # to retrieve the password. Only allow the specific computer account(s) hosting the service.
    $targetHostComputer = "SQLServerHost$"
    
    New-ADServiceAccount -Name $gMSAName `
        -DNSHostName "$gMSAName.domain.local" `
        -ManagedPasswordIntervalInDays 30 `
        -PrincipalsAllowedToRetrieveManagedPassword $targetHostComputer
        
    Write-Host "[+] gMSA '$gMSAName' created successfully." -ForegroundColor Green
} else {
    Write-Host "[-] gMSA '$gMSAName' already exists." -ForegroundColor Yellow
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-004" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-004] Restrict Kerberos Delegation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/restrict-kerberos-delegation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kerberos delegation allows a service to impersonate a user to access downstream resources on behalf of that user. In <xhtml:strong>Unconstrained Delegation</xhtml:strong>, when a user authenticates to a service, the user's Ticket Granting Ticket (TGT) is sent to the service server and stored in LSASS memory. If an attacker compromises that service server, they can extract the cached TGTs of all users who have authenticated to it (including Domain Admins) and impersonate them across the entire domain.</xhtml:p>
        <xhtml:p>To prevent this critical privilege escalation path, <xhtml:strong>Unconstrained Delegation must be banned entirely</xhtml:strong>. Any required delegation should be restricted to <xhtml:strong>Constrained Delegation</xhtml:strong> or <xhtml:strong>Resource-Based Constrained Delegation (RBCD)</xhtml:strong>, which specify exactly which target services can receive delegated credentials.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers Console Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Locate the computer or user account that has unconstrained delegation enabled.</xhtml:li>
          <xhtml:li>Right-click the object and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Go to the <xhtml:strong>Delegation</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Do not trust this computer for delegation</xhtml:strong> to disable unconstrained delegation.</xhtml:li>
          <xhtml:li>Alternatively, to configure Constrained Delegation:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select </xhtml:em>
            <xhtml:em>Trust this computer for delegation to specified services only</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select </xhtml:em>
            <xhtml:em>Use Kerberos only</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Use any authentication protocol</xhtml:em>* (S4U2Self/Protocol Transition).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Add</xhtml:em>* to specify the target services.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use the following PowerShell script to audit and disable unconstrained delegation on all computers and users.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-RestrictDelegation.ps1">Download Script: Set-RestrictDelegation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-RestrictDelegation.ps1
# Description: Disables unconstrained delegation on computer and user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Restrict Kerberos Delegation..." -ForegroundColor Cyan

# Find all computer accounts with Unconstrained Delegation
$unconstrainedComputers = Get-ADComputer -Filter {TrustedForDelegation -eq $true}
foreach ($comp in $unconstrainedComputers) {
    Write-Host "[*] Disabling Unconstrained Delegation on Computer: $($comp.SamAccountName)" -ForegroundColor Gray
    Set-ADComputer -Identity $comp -TrustedForDelegation $false
}

# Find all user accounts with Unconstrained Delegation
$unconstrainedUsers = Get-ADUser -Filter {TrustedForDelegation -eq $true}
foreach ($user in $unconstrainedUsers) {
    Write-Host "[*] Disabling Unconstrained Delegation on User: $($user.SamAccountName)" -ForegroundColor Gray
    Set-ADUser -Identity $user -TrustedForDelegation $false
}

Write-Host "Unconstrained delegation has been disabled on all identified accounts." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit delegation settings in the domain:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-KerberosDelegationStatus.ps1">Download Script: Get-KerberosDelegationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KerberosDelegationStatus.ps1
# Description: Audits accounts with unconstrained delegation in the Active Directory domain.

Import-Module ActiveDirectory

Write-Host "--- Auditing Kerberos Delegation Settings ---" -ForegroundColor Cyan

$unconstrainedComputers = Get-ADComputer -Filter {TrustedForDelegation -eq $true}
$unconstrainedUsers = Get-ADUser -Filter {TrustedForDelegation -eq $true}

$totalUnconstrained = $unconstrainedComputers.Count + $unconstrainedUsers.Count

if ($totalUnconstrained -eq 0) {
    Write-Host "[+] Secure: No accounts found with Unconstrained Delegation." -ForegroundColor Green
} else {
    foreach ($comp in $unconstrainedComputers) {
        Write-Host "[!] VULNERABLE: Computer with Unconstrained Delegation: $($comp.SamAccountName)" -ForegroundColor Red
    }
    foreach ($user in $unconstrainedUsers) {
        Write-Host "[!] VULNERABLE: User with Unconstrained Delegation: $($user.SamAccountName)" -ForegroundColor Red
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-RestrictDelegation.ps1
# Description: Disables unconstrained delegation on computer and user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Restrict Kerberos Delegation..." -ForegroundColor Cyan

# Find all computer accounts with Unconstrained Delegation
$unconstrainedComputers = Get-ADComputer -Filter {TrustedForDelegation -eq $true}
foreach ($comp in $unconstrainedComputers) {
    Write-Host "[*] Disabling Unconstrained Delegation on Computer: $($comp.SamAccountName)" -ForegroundColor Gray
    Set-ADComputer -Identity $comp -TrustedForDelegation $false
}

# Find all user accounts with Unconstrained Delegation
$unconstrainedUsers = Get-ADUser -Filter {TrustedForDelegation -eq $true}
foreach ($user in $unconstrainedUsers) {
    Write-Host "[*] Disabling Unconstrained Delegation on User: $($user.SamAccountName)" -ForegroundColor Gray
    Set-ADUser -Identity $user -TrustedForDelegation $false
}

Write-Host "Unconstrained delegation has been disabled on all identified accounts." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-005] Configure and Populate Protected Users Group</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/configure-protected-users-group.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Standard administrative accounts are highly vulnerable to credential harvesting attacks. If a Domain Admin or other high-privilege account authenticates to a compromised workstation or member server, their credentials (passwords, Kerberos TGTs, NTLM hashes) remain cached in the Local Security Authority Subsystem Service (LSASS) memory. Attackers can extract these credentials using tools like Mimikatz to escalate privileges or move laterally.</xhtml:p>
        <xhtml:p>The <xhtml:strong>Protected Users</xhtml:strong> security group (introduced in Windows Server 2012 R2) enforces non-configurable, highly secure authentication restrictions on its members. These protections include: 1. <xhtml:strong>No NTLM caching</xhtml:strong>: NTLM password hashes are not cached locally, and members cannot authenticate via NTLM. 2. <xhtml:strong>Short Kerberos TGT lifetimes</xhtml:strong>: Ticket Granting Tickets (TGTs) are limited to 4 hours and cannot be renewed beyond that. 3. <xhtml:strong>No weak encryption</xhtml:strong>: Members cannot use DES or RC4 encryption for Kerberos pre-authentication. 4. <xhtml:strong>No CredSSP or WDigest caching</xhtml:strong>: Cleartext credentials are never cached by the local system. 5. <xhtml:strong>No delegation</xhtml:strong>: Kerberos delegation (constrained or unconstrained) is blocked for accounts in this group.</xhtml:p>
        <xhtml:p>Placing Tier 0 and Tier 1 administrative accounts into the Protected Users group significantly reduces the threat of credential harvesting.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers Console Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Users</xhtml:strong> container (or where the built-in groups are located).</xhtml:li>
          <xhtml:li>Double-click the <xhtml:strong>Protected Users</xhtml:strong> security group.</xhtml:li>
          <xhtml:li>Click the <xhtml:strong>Members</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Add</xhtml:strong>.</xhtml:li>
          <xhtml:li>Type the names of the Tier 0 and Tier 1 administrative accounts (e.g., <xhtml:code>admin-t0-user</xhtml:code>) and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Ask the administrators to sign out and sign back in for the security group memberships to take effect.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to add administrative accounts to the Protected Users security group using PowerShell.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ProtectedUsers.ps1">Download Script: Set-ProtectedUsers.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ProtectedUsers.ps1
# Description: Adds privileged accounts to the Protected Users group.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Populate Protected Users Group..." -ForegroundColor Cyan

$GroupName = "Protected Users"
$TargetAdmins = @("admin-t0-user", "admin-t1-user")

foreach ($Admin in $TargetAdmins) {
    $User = Get-ADUser -Filter "SamAccountName -eq '$Admin'"
    
    if ($User) {
        # Check if already a member
        $isMember = Get-ADGroupMember -Identity $GroupName | Where-Object { $_.SamAccountName -eq $Admin }
        
        if (-not $isMember) {
            Add-ADGroupMember -Identity $GroupName -Members $User
            Write-Host "[+] Added $Admin to Protected Users group." -ForegroundColor Green
        } else {
            Write-Host "[-] User $Admin is already a member of Protected Users group." -ForegroundColor Yellow
        }
    } else {
        Write-Warning "User '$Admin' not found in Active Directory."
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the members of the Protected Users group:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-ProtectedUsersStatus.ps1">Download Script: Get-ProtectedUsersStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-ProtectedUsersStatus.ps1
# Description: Lists all members of the Protected Users security group.

Import-Module ActiveDirectory

Write-Host "--- Auditing Protected Users Group Members ---" -ForegroundColor Cyan

$GroupName = "Protected Users"
$Members = Get-ADGroupMember -Identity $GroupName -ErrorAction SilentlyContinue

if ($Members) {
    Write-Host "[+] Members of the Protected Users group:" -ForegroundColor Green
    foreach ($Member in $Members) {
        Write-Host "    - $($Member.SamAccountName) (Type: $($Member.objectClass))" -ForegroundColor White
    }
} else {
    Write-Host "[!] VULNERABLE: No members found in the Protected Users group. Administrative accounts may be unprotected." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ProtectedUsers.ps1
# Description: Adds privileged accounts to the Protected Users group.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Populate Protected Users Group..." -ForegroundColor Cyan

$GroupName = "Protected Users"
$TargetAdmins = @("admin-t0-user", "admin-t1-user")

foreach ($Admin in $TargetAdmins) {
    $User = Get-ADUser -Filter "SamAccountName -eq '$Admin'"
    
    if ($User) {
        # Check if already a member
        $isMember = Get-ADGroupMember -Identity $GroupName | Where-Object { $_.SamAccountName -eq $Admin }
        
        if (-not $isMember) {
            Add-ADGroupMember -Identity $GroupName -Members $User
            Write-Host "[+] Added $Admin to Protected Users group." -ForegroundColor Green
        } else {
            Write-Host "[-] User $Admin is already a member of Protected Users group." -ForegroundColor Yellow
        }
    } else {
        Write-Warning "User '$Admin' not found in Active Directory."
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-006" severity="medium" weight="10.0" selected="false">
      <title>[REQ-ID-006] Rename and Disable Default Administrator and Guest Accounts</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/harden-default-accounts.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory and local Windows environments initialize built-in accounts with fixed Relative Identifiers (RIDs). The default Administrator account always has RID 500, and the Guest account always has RID 501.</xhtml:p>
        <xhtml:p>Because these accounts are well-known, they are frequent targets for automated brute-force, password guessing, and identity enumeration attacks. In many environments, the built-in local administrator account has the same password across multiple systems, allowing attackers to move laterally if they crack one machine. Renaming these accounts increases the complexity of target identification, while disabling them prevents unauthorized logons entirely. If LAPS is active, it can rotate the password of the local administrator account even when the account is disabled, preserving safe recovery options.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the appropriate hardening GPO (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code> or <xhtml:code>GPO_Hardening_MemberServers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Accounts: Administrator account status</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Accounts: Guest account status</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Accounts: Rename administrator account</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: Enter a non-obvious custom name (e.g., <xhtml:code>LocalMgmtAdmin</xhtml:code>).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Accounts: Rename guest account</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: Enter a non-obvious custom name (e.g., <xhtml:code>LocalMgmtGuest</xhtml:code>).</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to disable the local Administrator and Guest accounts locally using PowerShell.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-HardenDefaultAccounts.ps1">Download Script: Set-HardenDefaultAccounts.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-HardenDefaultAccounts.ps1
# Description: Disables and renames the built-in local Administrator and Guest accounts locally.

Write-Host "Applying hardening requirement: Rename and Disable Default Accounts..." -ForegroundColor Cyan

# 1. Disable and rename built-in local Administrator account
$adminAccount = Get-LocalUser | Where-Object { $_.SID -like "*-500" }
if ($adminAccount) {
    if ($adminAccount.Enabled) {
        Disable-LocalUser -Name $adminAccount.Name
        Write-Host "[+] Local Administrator account ($($adminAccount.Name)) disabled." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Administrator account ($($adminAccount.Name)) is already disabled." -ForegroundColor Yellow
    }
    
    if ($adminAccount.Name -eq "Administrator") {
        Rename-LocalUser -Name "Administrator" -NewName "LocalMgmtAdmin"
        Write-Host "[+] Local Administrator account renamed to LocalMgmtAdmin." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Administrator account is already renamed ($($adminAccount.Name))." -ForegroundColor Yellow
    }
} else {
    Write-Warning "Built-in local Administrator account not found."
}

# 2. Disable and rename built-in local Guest account
$guestAccount = Get-LocalUser | Where-Object { $_.SID -like "*-501" }
if ($guestAccount) {
    if ($guestAccount.Enabled) {
        Disable-LocalUser -Name $guestAccount.Name
        Write-Host "[+] Local Guest account ($($guestAccount.Name)) disabled." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Guest account ($($guestAccount.Name)) is already disabled." -ForegroundColor Yellow
    }
    
    if ($guestAccount.Name -eq "Guest") {
        Rename-LocalUser -Name "Guest" -NewName "LocalMgmtGuest"
        Write-Host "[+] Local Guest account renamed to LocalMgmtGuest." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Guest account is already renamed ($($guestAccount.Name))." -ForegroundColor Yellow
    }
} else {
    Write-Warning "Built-in local Guest account not found."
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit default accounts status locally:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-DefaultAccountsStatus.ps1">Download Script: Get-DefaultAccountsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DefaultAccountsStatus.ps1
# Description: Audits the enabled status of the built-in local Administrator and Guest accounts.

Write-Host "--- Auditing Default Accounts Status ---" -ForegroundColor Cyan

$adminAccount = Get-LocalUser | Where-Object { $_.SID -like "*-500" }
$guestAccount = Get-LocalUser | Where-Object { $_.SID -like "*-501" }

if ($adminAccount) {
    $adminColor = if ($adminAccount.Enabled) { "Red" } else { "Green" }
    Write-Host "    - Local Administrator ($($adminAccount.Name)): Enabled = $($adminAccount.Enabled)" -ForegroundColor $adminColor
}

if ($guestAccount) {
    $guestColor = if ($guestAccount.Enabled) { "Red" } else { "Green" }
    Write-Host "    - Local Guest ($($guestAccount.Name)): Enabled = $($guestAccount.Enabled)" -ForegroundColor $guestColor
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-HardenDefaultAccounts.ps1
# Description: Disables and renames the built-in local Administrator and Guest accounts locally.

Write-Host "Applying hardening requirement: Rename and Disable Default Accounts..." -ForegroundColor Cyan

# 1. Disable and rename built-in local Administrator account
$adminAccount = Get-LocalUser | Where-Object { $_.SID -like "*-500" }
if ($adminAccount) {
    if ($adminAccount.Enabled) {
        Disable-LocalUser -Name $adminAccount.Name
        Write-Host "[+] Local Administrator account ($($adminAccount.Name)) disabled." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Administrator account ($($adminAccount.Name)) is already disabled." -ForegroundColor Yellow
    }
    
    if ($adminAccount.Name -eq "Administrator") {
        Rename-LocalUser -Name "Administrator" -NewName "LocalMgmtAdmin"
        Write-Host "[+] Local Administrator account renamed to LocalMgmtAdmin." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Administrator account is already renamed ($($adminAccount.Name))." -ForegroundColor Yellow
    }
} else {
    Write-Warning "Built-in local Administrator account not found."
}

# 2. Disable and rename built-in local Guest account
$guestAccount = Get-LocalUser | Where-Object { $_.SID -like "*-501" }
if ($guestAccount) {
    if ($guestAccount.Enabled) {
        Disable-LocalUser -Name $guestAccount.Name
        Write-Host "[+] Local Guest account ($($guestAccount.Name)) disabled." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Guest account ($($guestAccount.Name)) is already disabled." -ForegroundColor Yellow
    }
    
    if ($guestAccount.Name -eq "Guest") {
        Rename-LocalUser -Name "Guest" -NewName "LocalMgmtGuest"
        Write-Host "[+] Local Guest account renamed to LocalMgmtGuest." -ForegroundColor Green
    } else {
        Write-Host "[-] Local Guest account is already renamed ($($guestAccount.Name))." -ForegroundColor Yellow
    }
} else {
    Write-Warning "Built-in local Guest account not found."
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-007" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-007] Restrict Interactive Logons for Service Accounts</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/restrict-service-account-logons.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Service accounts are frequent targets of brute-force and Kerberoasting attacks. If an adversary successfully cracks a service account's password offline, their immediate next step is to use those credentials to log on to domain systems to establish a footprint, dump credentials from memory, or perform administrative tasks.</xhtml:p>
        <xhtml:p>By enforcing User Rights Assignment policies that explicitly deny service accounts the ability to log on locally (at the physical console) or through Remote Desktop Services (RDP), the threat of an interactive domain compromise via service credentials is neutralized. Even if a service account password is compromised, the attacker cannot utilize it to gain an interactive command shell or graphical desktop session on network endpoints or servers.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to all domain systems (e.g., <xhtml:code>GPO_Hardening_DomainMembers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deny log on locally</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>
            <xhtml:em>: Define this policy and click </xhtml:em>
            <xhtml:em>Add User or Group</xhtml:em>*. Add the dedicated security group containing all service accounts (e.g., <xhtml:code>domain\Grp_ServiceAccounts</xhtml:code> or <xhtml:code>domain\Domain Users</xhtml:code> if restricting specific sub-groups).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deny log on through Remote Desktop Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>
            <xhtml:em>: Define this policy and click </xhtml:em>
            <xhtml:em>Add User or Group</xhtml:em>*. Add the dedicated security group containing all service accounts.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Force a policy update on target servers (<xhtml:code>gpupdate /force</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Since User Rights Assignment is typically controlled by GPO or local security policy database (<xhtml:code>secedit.sdb</xhtml:code>), local changes can be made using the <xhtml:code>secedit</xhtml:code> command-line utility.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DenyServiceLogons.ps1">Download Script: Set-DenyServiceLogons.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DenyServiceLogons.ps1
# Description: Configures local security database to deny interactive logons for a service account group.

Write-Host "Applying hardening requirement: Restrict Interactive Logons for Service Accounts..." -ForegroundColor Cyan

$SecDb = "$($env:temp)\localpolicy.sdb"
$SecCfg = "$($env:temp)\localpolicy.inf"
$GroupName = "Grp_ServiceAccounts" # Replace with the target security group name

# Export current security policy
secedit /export /cfg $SecCfg /quiet

# Read configuration file
$cfgContent = Get-Content -Path $SecCfg

# Define logon rights lines
$DenyLocalLine = "SeDenyInteractiveLogonRight = $GroupName"
$DenyRdpLine = "SeDenyRemoteInteractiveLogonRight = $GroupName"

# Check and update policy lines
$hasDenyLocal = $false
$hasDenyRdp = $false

$newCfg = New-Object System.Collections.Generic.List[string]

foreach ($line in $cfgContent) {
    if ($line -like "SeDenyInteractiveLogonRight*") {
        if ($line -notlike "*$GroupName*") {
            $line = "$($line), $GroupName"
        }
        $hasDenyLocal = $true
    }
    if ($line -like "SeDenyRemoteInteractiveLogonRight*") {
        if ($line -notlike "*$GroupName*") {
            $line = "$($line), $GroupName"
        }
        $hasDenyRdp = $true
    }
    $newCfg.Add($line) | Out-Null
}

if (-not $hasDenyLocal) {
    # Add to [Privilege Rights] section
    $privIndex = $newCfg.IndexOf("[Privilege Rights]")
    if ($privIndex -ge 0) {
        $newCfg.Insert($privIndex + 1, $DenyLocalLine)
    }
}

if (-not $hasDenyRdp) {
    $privIndex = $newCfg.IndexOf("[Privilege Rights]")
    if ($privIndex -ge 0) {
        $newCfg.Insert($privIndex + 1, $DenyRdpLine)
    }
}

# Save updated configuration
$newCfg | Set-Content -Path $SecCfg

# Configure local security policy
secedit /configure /db $SecDb /cfg $SecCfg /areas USER_RIGHTS /quiet

# Cleanup temporary files
Remove-Item -Path $SecCfg -Force
Remove-Item -Path $SecDb -Force

Write-Host "Local security policy updated: Deny log on locally/RDP applied to group $GroupName." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local User Rights Assignment settings:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-DenyServiceLogonsStatus.ps1">Download Script: Get-DenyServiceLogonsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DenyServiceLogonsStatus.ps1
# Description: Audits the Deny logon rights configurations locally.

Write-Host "--- Auditing Deny Logon Rights ---" -ForegroundColor Cyan

$SecCfg = "$($env:temp)\auditpolicy.inf"
secedit /export /cfg $SecCfg /quiet

$cfgContent = Get-Content -Path $SecCfg
$denyLocal = $cfgContent | Where-Object { $_ -like "SeDenyInteractiveLogonRight*" }
$denyRdp = $cfgContent | Where-Object { $_ -like "SeDenyRemoteInteractiveLogonRight*" }

Write-Host "[+] Local Deny Logon Rights settings:" -ForegroundColor Green
if ($denyLocal) {
    Write-Host "    - $denyLocal" -ForegroundColor White
} else {
    Write-Host "    - SeDenyInteractiveLogonRight is not configured." -ForegroundColor Yellow
}

if ($denyRdp) {
    Write-Host "    - $denyRdp" -ForegroundColor White
} else {
    Write-Host "    - SeDenyRemoteInteractiveLogonRight is not configured." -ForegroundColor Yellow
}

Remove-Item -Path $SecCfg -Force</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DenyServiceLogons.ps1
# Description: Configures local security database to deny interactive logons for a service account group.

Write-Host "Applying hardening requirement: Restrict Interactive Logons for Service Accounts..." -ForegroundColor Cyan

$SecDb = "$($env:temp)\localpolicy.sdb"
$SecCfg = "$($env:temp)\localpolicy.inf"
$GroupName = "Grp_ServiceAccounts" # Replace with the target security group name

# Export current security policy
secedit /export /cfg $SecCfg /quiet

# Read configuration file
$cfgContent = Get-Content -Path $SecCfg

# Define logon rights lines
$DenyLocalLine = "SeDenyInteractiveLogonRight = $GroupName"
$DenyRdpLine = "SeDenyRemoteInteractiveLogonRight = $GroupName"

# Check and update policy lines
$hasDenyLocal = $false
$hasDenyRdp = $false

$newCfg = New-Object System.Collections.Generic.List[string]

foreach ($line in $cfgContent) {
    if ($line -like "SeDenyInteractiveLogonRight*") {
        if ($line -notlike "*$GroupName*") {
            $line = "$($line), $GroupName"
        }
        $hasDenyLocal = $true
    }
    if ($line -like "SeDenyRemoteInteractiveLogonRight*") {
        if ($line -notlike "*$GroupName*") {
            $line = "$($line), $GroupName"
        }
        $hasDenyRdp = $true
    }
    $newCfg.Add($line) | Out-Null
}

if (-not $hasDenyLocal) {
    # Add to [Privilege Rights] section
    $privIndex = $newCfg.IndexOf("[Privilege Rights]")
    if ($privIndex -ge 0) {
        $newCfg.Insert($privIndex + 1, $DenyLocalLine)
    }
}

if (-not $hasDenyRdp) {
    $privIndex = $newCfg.IndexOf("[Privilege Rights]")
    if ($privIndex -ge 0) {
        $newCfg.Insert($privIndex + 1, $DenyRdpLine)
    }
}

# Save updated configuration
$newCfg | Set-Content -Path $SecCfg

# Configure local security policy
secedit /configure /db $SecDb /cfg $SecCfg /areas USER_RIGHTS /quiet

# Cleanup temporary files
Remove-Item -Path $SecCfg -Force
Remove-Item -Path $SecDb -Force

Write-Host "Local security policy updated: Deny log on locally/RDP applied to group $GroupName." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3007" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-008" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-008] Enforce User and Service Account Kerberos Encryption (AES-Only)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/enforce-user-aes-encryption.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In Active Directory, even when Group Policies restrict Kerberos encryption algorithms on domain members, individual user and service accounts can override these restrictions during authentication negotiation. If an account has obsolete encryption types enabled (e.g., RC4 or DES) or has the <xhtml:code>msDS-SupportedEncryptionTypes</xhtml:code> attribute set to <xhtml:code>0</xhtml:code> (default, which defaults to domain controllers' allowed options), the Key Distribution Center (KDC) may issue Service tickets (TGS) using the RC4 algorithm.</xhtml:p>
        <xhtml:p>Because RC4 utilizes weaker, legacy cryptography, tickets encrypted using RC4 can be easily extracted and cracked offline (Kerberoasting) by adversaries. Explicitly configuring the <xhtml:code>msDS-SupportedEncryptionTypes</xhtml:code> attribute to <xhtml:code>24</xhtml:code> (AES128 = 8 + AES256 = 16) on Active Directory accounts ensures that the KDC only negotiates AES encryption types, securing the authentication credentials against offline brute-forcing and ticket forgery.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers Attribute Editor (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Select <xhtml:strong>View</xhtml:strong> from the menu bar and check <xhtml:strong>Advanced Features</xhtml:strong>.</xhtml:li>
          <xhtml:li>Locate the target user or service account.</xhtml:li>
          <xhtml:li>Right-click the object and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Attribute Editor</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Scroll down and double-click the <xhtml:code>msDS-SupportedEncryptionTypes</xhtml:code> attribute.</xhtml:li>
          <xhtml:li>Set the value to <xhtml:code>24</xhtml:code> (Decimal) and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Go to the <xhtml:strong>Account</xhtml:strong> tab and verify that under <xhtml:strong>Account options</xhtml:strong>, <xhtml:code>This account supports Kerberos AES 128 bit encryption</xhtml:code> and <xhtml:code>This account supports Kerberos AES 256 bit encryption</xhtml:code> are checked, while RC4/DES are not forced.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to enforce AES-only encryption on active user accounts in the domain.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-AccountAESEncryption.ps1">Download Script: Set-AccountAESEncryption.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-AccountAESEncryption.ps1
# Description: Configures the msDS-SupportedEncryptionTypes attribute to AES-only (24) on active user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce AES-Only Kerberos Encryption on Accounts..." -ForegroundColor Cyan

# 24 represents AES128 (8) + AES256 (16)
$AESValue = 24
$TargetUsers = Get-ADUser -Filter {Enabled -eq $true}

foreach ($User in $TargetUsers) {
    # Retrieve current attribute value
    $currUser = Get-ADUser -Identity $User -Properties msDS-SupportedEncryptionTypes
    $currVal = $currUser."msDS-SupportedEncryptionTypes"
    
    if ($currVal -ne $AESValue) {
        Write-Host "[*] Enforcing AES encryption on account: $($User.SamAccountName)" -ForegroundColor Gray
        Set-ADUser -Identity $User -Replace @{"msDS-SupportedEncryptionTypes" = $AESValue}
    }
}

Write-Host "AES encryption has been successfully enforced on active accounts." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit account Kerberos encryption configuration:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AccountEncryptionStatus.ps1">Download Script: Get-AccountEncryptionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AccountEncryptionStatus.ps1
# Description: Identifies accounts that do not have msDS-SupportedEncryptionTypes set to 24 (AES-only).

Import-Module ActiveDirectory

Write-Host "--- Auditing Account Kerberos Encryption Configuration ---" -ForegroundColor Cyan

$VulnerableAccounts = Get-ADUser -Filter {Enabled -eq $true} -Properties msDS-SupportedEncryptionTypes | Where-Object { $_."msDS-SupportedEncryptionTypes" -ne 24 }

if ($VulnerableAccounts) {
    Write-Host "[!] Accounts not configured for AES-only (msDS-SupportedEncryptionTypes != 24):" -ForegroundColor Red
    foreach ($Acct in $VulnerableAccounts) {
        $Val = $Acct."msDS-SupportedEncryptionTypes"
        if ($null -eq $Val) { $Val = "Not Set (0)" }
        Write-Host "    - $($Acct.SamAccountName) | Value: $Val" -ForegroundColor White
    }
} else {
    Write-Host "[+] Secure: All active accounts are configured for AES-only Kerberos encryption." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-AccountAESEncryption.ps1
# Description: Configures the msDS-SupportedEncryptionTypes attribute to AES-only (24) on active user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce AES-Only Kerberos Encryption on Accounts..." -ForegroundColor Cyan

# 24 represents AES128 (8) + AES256 (16)
$AESValue = 24
$TargetUsers = Get-ADUser -Filter {Enabled -eq $true}

foreach ($User in $TargetUsers) {
    # Retrieve current attribute value
    $currUser = Get-ADUser -Identity $User -Properties msDS-SupportedEncryptionTypes
    $currVal = $currUser."msDS-SupportedEncryptionTypes"
    
    if ($currVal -ne $AESValue) {
        Write-Host "[*] Enforcing AES encryption on account: $($User.SamAccountName)" -ForegroundColor Gray
        Set-ADUser -Identity $User -Replace @{"msDS-SupportedEncryptionTypes" = $AESValue}
    }
}

Write-Host "AES encryption has been successfully enforced on active accounts." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3008" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-009" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-009] Enforce Kerberos Pre-Authentication</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Active Directory User Accounts)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/enforce-kerberos-preauthentication.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kerberos Pre-Authentication serves as the primary line of defense against AS-REP Roasting. AS-REP Roasting is a credential theft technique where attackers target accounts that do not require Kerberos pre-authentication.</xhtml:p>
        <xhtml:p>Without pre-authentication: 1. <xhtml:strong>Unauthenticated Requesting</xhtml:strong>: The Key Distribution Center (KDC) will issue a Ticket Granting Ticket (TGT) encrypted with the user's secret key (derived from their password) to any client that requests it, without requiring the client to authenticate or prove identity first. 2. <xhtml:strong>Offline Password Cracking</xhtml:strong>: An attacker can request a TGT for a target user, intercept the KDC's response (AS-REP payload), and take the encrypted data offline. They can then perform brute-force or dictionary attacks to crack the password hash without triggering account lockout policies or generating logon failure logs.</xhtml:p>
        <xhtml:p>By enforcing pre-authentication, the KDC requires the client to encrypt a timestamp using their password hash before issuing the TGT. This proves the client possesses the password, preventing attackers from retrieving the encrypted AS-REP token for offline cracking.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller or administrative workstation with <xhtml:strong>Account Operators</xhtml:strong> or <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Locate the target user account, right-click it, and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Account</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>In the <xhtml:strong>Account options</xhtml:strong> list, scroll down and ensure that the checkbox for <xhtml:strong>Do not require Kerberos preauthentication</xhtml:strong> is <xhtml:strong>unchecked</xhtml:strong> (disabled).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and remediate accounts in the forest.</xhtml:p>
        <xhtml:h4>1. Local AD Audit (Audit-KerberosPreAuth.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-KerberosPreAuth.ps1">Download Script: Audit-KerberosPreAuth.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-KerberosPreAuth.ps1
# Description: Audits active user accounts to find any with pre-authentication disabled.

Import-Module ActiveDirectory

Write-Host "--- Auditing Kerberos Pre-Authentication Status ---" -ForegroundColor Cyan

try {
    # Search for enabled accounts with DONOTREQ_PREAUTH (0x400000) active
    $VulnerableAccounts = Get-ADUser -Filter "DoesNotRequirePreAuth -eq '$true'" -Properties DoesNotRequirePreAuth, Enabled | Where-Object { $_.Enabled -eq $true }
    
    if ($VulnerableAccounts) {
        Write-Host "`nVULNERABLE: Found $($VulnerableAccounts.Count) enabled user account(s) with Kerberos Pre-Authentication disabled:" -ForegroundColor Red
        foreach ($acc in $VulnerableAccounts) {
            Write-Host "    - User: $($acc.SamAccountName) | DN: $($acc.DistinguishedName)" -ForegroundColor White
        }
    } else {
        Write-Host "`nStatus: Compliant. All enabled user accounts require Kerberos Pre-Authentication." -ForegroundColor Green
    }
} catch {
    Write-Host "VULNERABLE: Could not audit accounts. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local AD Remediation (Set-KerberosPreAuth.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-KerberosPreAuth.ps1">Download Script: Set-KerberosPreAuth.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-KerberosPreAuth.ps1
# Description: Enforces Kerberos Pre-Authentication on all active user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce Kerberos Pre-Authentication..." -ForegroundColor Cyan

try {
    $VulnerableAccounts = Get-ADUser -Filter "DoesNotRequirePreAuth -eq '$true'" -Properties DoesNotRequirePreAuth, Enabled | Where-Object { $_.Enabled -eq $true }
    
    if ($VulnerableAccounts) {
        Write-Host "[+] Found $($VulnerableAccounts.Count) accounts requiring remediation." -ForegroundColor Yellow
        foreach ($acc in $VulnerableAccounts) {
            Set-ADAccountControl -Identity $acc.SamAccountName -DoesNotRequirePreAuth $false -ErrorAction Stop
            Write-Host "    Remediated: $($acc.SamAccountName)" -ForegroundColor Green
        }
        Write-Host "[+] All target accounts successfully remediated." -ForegroundColor Green
    } else {
        Write-Host "[+] No vulnerable accounts found. Pre-Authentication is already enforced." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to enforce Kerberos Pre-Authentication. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-KerberosPreAuth.ps1
# Description: Enforces Kerberos Pre-Authentication on all active user accounts.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce Kerberos Pre-Authentication..." -ForegroundColor Cyan

try {
    $VulnerableAccounts = Get-ADUser -Filter "DoesNotRequirePreAuth -eq '$true'" -Properties DoesNotRequirePreAuth, Enabled | Where-Object { $_.Enabled -eq $true }
    
    if ($VulnerableAccounts) {
        Write-Host "[+] Found $($VulnerableAccounts.Count) accounts requiring remediation." -ForegroundColor Yellow
        foreach ($acc in $VulnerableAccounts) {
            Set-ADAccountControl -Identity $acc.SamAccountName -DoesNotRequirePreAuth $false -ErrorAction Stop
            Write-Host "    Remediated: $($acc.SamAccountName)" -ForegroundColor Green
        }
        Write-Host "[+] All target accounts successfully remediated." -ForegroundColor Green
    } else {
        Write-Host "[+] No vulnerable accounts found. Pre-Authentication is already enforced." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to enforce Kerberos Pre-Authentication. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3009" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-010" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-010] Restrict Schema Administrators Group Membership</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/restrict-schema-admins.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Schema Admins group is one of the most critical security groups within an Active Directory forest. This group controls the underlying structure of the directory database, defining every class of object and every attribute that those objects can possess.</xhtml:p>
        <xhtml:p>A compromised Schema Admin account poses a massive risk to the forest: 1. <xhtml:strong>Schema Modifications</xhtml:strong>: Attackers can modify class definitions, introduce rogue attributes, or insert persistent directory-level backdoors that survive standard OS-level remediation. 2. <xhtml:strong>Low Operational Frequency</xhtml:strong>: Schema modifications are extremely rare, typically occurring only during major enterprise software installations (such as Exchange, SCCM) or AD functional level upgrades.</xhtml:p>
        <xhtml:p>To minimize the attack surface, standard administrative accounts must not have permanent membership in the Schema Admins group. Instead, membership must be granted strictly on a Just-In-Time (JIT) basis and revoked immediately after schema changes are completed. Locking the group membership to empty using a Restricted Groups GPO ensures that any unauthorized or accidental additions are automatically cleared.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a management workstation or Domain Controller with <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create a new GPO named <xhtml:code>SEC_Forest_RestrictedGroups</xhtml:code> and link it to the <xhtml:strong>Domain Controllers</xhtml:strong> OU in the forest root domain.</xhtml:li>
          <xhtml:li>Right-click the GPO and select <xhtml:strong>Edit</xhtml:strong> to open the Group Policy Management Editor.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration &gt; Policies &gt; Windows Settings &gt; Security Settings &gt; Restricted Groups</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Restricted Groups</xhtml:strong> and select <xhtml:strong>Add Group</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the Group box, type or browse for <xhtml:strong>Schema Admins</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the properties dialog for Schema Admins:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Leave the list under </xhtml:em>
            <xhtml:em>Members of this group</xhtml:em>* completely blank.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Leave the list under </xhtml:em>
            <xhtml:em>This group is a member of</xhtml:em>* completely blank.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>The group membership will be automatically checked and cleared on Domain Controllers during Group Policy refresh cycles.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and clear the group membership.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-SchemaAdminsGroup.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-SchemaAdminsGroup.ps1">Download Script: Audit-SchemaAdminsGroup.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-SchemaAdminsGroup.ps1
# Description: Audits the Schema Admins group membership.

Import-Module ActiveDirectory

Write-Host "--- Auditing Schema Admins Group Membership ---" -ForegroundColor Cyan

try {
    $Group = Get-ADGroup -Identity "Schema Admins" -Properties Members -ErrorAction Stop
    $MembersCount = $Group.Members.Count
    
    if ($MembersCount -gt 0) {
        Write-Host "`nVULNERABLE: Schema Admins group is NOT empty. Found $MembersCount member(s):" -ForegroundColor Red
        foreach ($memberDN in $Group.Members) {
            $memberObj = Get-ADObject -Identity $memberDN -ErrorAction SilentlyContinue
            Write-Host "    - Member: $($memberObj.Name) | DN: $memberDN" -ForegroundColor White
        }
    } else {
        Write-Host "`nStatus: Compliant. Schema Admins group is empty." -ForegroundColor Green
    }
} catch {
    Write-Host "VULNERABLE: Could not query Schema Admins group. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Clear-SchemaAdminsGroup.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Clear-SchemaAdminsGroup.ps1">Download Script: Clear-SchemaAdminsGroup.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Clear-SchemaAdminsGroup.ps1
# Description: Removes all members from the Schema Admins group.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Clear Schema Admins group membership..." -ForegroundColor Cyan

try {
    $Group = Get-ADGroup -Identity "Schema Admins" -Properties Members -ErrorAction Stop
    
    if ($Group.Members.Count -gt 0) {
        Write-Host "[+] Found $($Group.Members.Count) members in Schema Admins group." -ForegroundColor Yellow
        foreach ($memberDN in $Group.Members) {
            $memberObj = Get-ADObject -Identity $memberDN
            Remove-ADGroupMember -Identity "Schema Admins" -Members $memberDN -Confirm:$false -ErrorAction Stop
            Write-Host "    Removed member: $($memberObj.Name)" -ForegroundColor Green
        }
        Write-Host "[+] Schema Admins group cleared successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] Schema Admins group is already empty." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to clear Schema Admins group. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Clear-SchemaAdminsGroup.ps1
# Description: Removes all members from the Schema Admins group.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Clear Schema Admins group membership..." -ForegroundColor Cyan

try {
    $Group = Get-ADGroup -Identity "Schema Admins" -Properties Members -ErrorAction Stop
    
    if ($Group.Members.Count -gt 0) {
        Write-Host "[+] Found $($Group.Members.Count) members in Schema Admins group." -ForegroundColor Yellow
        foreach ($memberDN in $Group.Members) {
            $memberObj = Get-ADObject -Identity $memberDN
            Remove-ADGroupMember -Identity "Schema Admins" -Members $memberDN -Confirm:$false -ErrorAction Stop
            Write-Host "    Removed member: $($memberObj.Name)" -ForegroundColor Green
        }
        Write-Host "[+] Schema Admins group cleared successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] Schema Admins group is already empty." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to clear Schema Admins group. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-011" severity="medium" weight="10.0" selected="false">
      <title>[REQ-ID-011] Enforce Accidental Deletion Protection on Organizational Units</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/prevent-accidental-deletion-ous.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Organizational Units (OUs) act as the logical containers for structuring users, groups, and computers in Active Directory, and are the targets for linking Group Policy Objects (GPOs).</xhtml:p>
        <xhtml:p>Enforcing the accidental deletion protection property provides the following security and availability benefits: 1. <xhtml:strong>Administrative Safeguard</xhtml:strong>: Drag-and-drop mistakes or batch scripting errors can lead to the deletion of an entire OU hierarchy, causing severe outages and loss of access controls. This feature places a "Deny" Access Control Entry (ACE) for the "Everyone" group on the "Delete" and "Delete Subtree" permissions of the object. 2. <xhtml:strong>Operational Continuity</xhtml:strong>: While it does not prevent a malicious administrator from intentionally disabling the setting and deleting the OU, it forces a deliberate, two-step verification process before any destructive actions can be performed.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a management workstation or Domain Controller with <xhtml:strong>Domain Admins</xhtml:strong> or <xhtml:strong>Account Operators</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>In the top menu, click <xhtml:strong>View</xhtml:strong> and ensure that <xhtml:strong>Advanced Features</xhtml:strong> is checked. This is required to expose the Object tab in properties.</xhtml:li>
          <xhtml:li>Locate the target Organizational Unit, right-click it, and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Object</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Check the box for <xhtml:strong>Protect object from accidental deletion</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and configure the setting domain-wide.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-OUAccidentalDeletion.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-OUAccidentalDeletion.ps1">Download Script: Audit-OUAccidentalDeletion.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-OUAccidentalDeletion.ps1
# Description: Audits all OUs to find any without accidental deletion protection.

Import-Module ActiveDirectory

Write-Host "--- Auditing OU Accidental Deletion Protection ---" -ForegroundColor Cyan

try {
    $UnprotectedOUs = Get-ADOrganizationalUnit -Filter "ProtectedFromAccidentalDeletion -eq '$false'" -ErrorAction Stop
    
    if ($UnprotectedOUs) {
        Write-Host "`nVULNERABLE: Found $($UnprotectedOUs.Count) Organizational Unit(s) without accidental deletion protection:" -ForegroundColor Red
        foreach ($ou in $UnprotectedOUs) {
            Write-Host "    - OU: $($ou.Name) | DN: $($ou.DistinguishedName)" -ForegroundColor White
        }
    } else {
        Write-Host "`nStatus: Compliant. All Organizational Units are protected from accidental deletion." -ForegroundColor Green
    }
} catch {
    Write-Host "VULNERABLE: Could not audit OUs. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Enforce-OUAccidentalDeletion.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enforce-OUAccidentalDeletion.ps1">Download Script: Enforce-OUAccidentalDeletion.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enforce-OUAccidentalDeletion.ps1
# Description: Enables accidental deletion protection on all OUs in the domain.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce OU Accidental Deletion Protection..." -ForegroundColor Cyan

try {
    $UnprotectedOUs = Get-ADOrganizationalUnit -Filter "ProtectedFromAccidentalDeletion -eq '$false'" -ErrorAction Stop
    
    if ($UnprotectedOUs) {
        Write-Host "[+] Found $($UnprotectedOUs.Count) OUs requiring protection." -ForegroundColor Yellow
        foreach ($ou in $UnprotectedOUs) {
            Set-ADOrganizationalUnit -Identity $ou.DistinguishedName -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "    Protected OU: $($ou.Name)" -ForegroundColor Green
        }
        Write-Host "[+] All Organizational Units are now protected." -ForegroundColor Green
    } else {
        Write-Host "[+] No unprotected OUs found." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to enable protection on OUs. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enforce-OUAccidentalDeletion.ps1
# Description: Enables accidental deletion protection on all OUs in the domain.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Enforce OU Accidental Deletion Protection..." -ForegroundColor Cyan

try {
    $UnprotectedOUs = Get-ADOrganizationalUnit -Filter "ProtectedFromAccidentalDeletion -eq '$false'" -ErrorAction Stop
    
    if ($UnprotectedOUs) {
        Write-Host "[+] Found $($UnprotectedOUs.Count) OUs requiring protection." -ForegroundColor Yellow
        foreach ($ou in $UnprotectedOUs) {
            Set-ADOrganizationalUnit -Identity $ou.DistinguishedName -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "    Protected OU: $($ou.Name)" -ForegroundColor Green
        }
        Write-Host "[+] All Organizational Units are now protected." -ForegroundColor Green
    } else {
        Write-Host "[+] No unprotected OUs found." -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to enable protection on OUs. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-012" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-012] Configure Active Directory Authentication Silos and Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Tier 0 Administration Workstations (PAWs), Tier 0 Administrator Accounts, Tier 0 Managed Service Accounts (gMSAs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025, Windows 10 Enterprise / Pro (1809+), Windows 11 Enterprise / Pro</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/configure-authentication-silos.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Standard Active Directory access control models rely on Discretionary Access Control Lists (DACLs) and security group memberships. While DACLs determine which directory objects or network shares an administrative account can modify, they do not restrict the physical or virtual systems from which that administrator can log on.</xhtml:p>
        <xhtml:p>In an active enterprise network, if a Tier 0 administrator (such as a Domain Admin or Enterprise Admin) authenticates from or logs on to a compromised Tier 1 server (e.g., an application host) or a Tier 2 workstation (e.g., a standard user workstation), their authentication material is loaded into the memory of the Local Security Authority Subsystem Service (LSASS). Attackers with local administrative control over that lower-tier system can scrape LSASS memory using credential-harvesting tools (such as Mimikatz) to extract Kerberos Ticket Granting Tickets (TGTs), NTLM password hashes, or plaintext credentials, resulting in total forest compromise via lateral movement and privilege escalation (Pass-the-Hash, Pass-the-Ticket).</xhtml:p>
        <xhtml:p>Authentication Policies and Authentication Policy Silos (introduced in Windows Server 2012 R2) provide cryptographic containment enforced directly at the Key Distribution Center (KDC) on Domain Controllers:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Cryptographic Boundary Enforcement at KDC</xhtml:strong>:</xhtml:li>
          <xhtml:li>Unlike host-level software restrictions or traditional group memberships, Authentication Silos are evaluated by the KDC during the Kerberos ticket acquisition phase (AS-REQ and TGS-REQ). When an account assigned to an Authentication Policy Silo requests a Kerberos ticket, the KDC inspects the client host's device claims (<xhtml:code>@Device.ad:silo</xhtml:code>). If the host is not enrolled in the same silo, the KDC unconditionally rejects ticket issuance with the Kerberos status code <xhtml:code>KDC_ERR_POLICY</xhtml:code> (<xhtml:code>0x12</xhtml:code>). Because ticket issuance is denied at the domain controller level, administrative credentials are never exposed, transmitted, or cached on unauthorized workstations.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Dynamic Access Control (DAC) &amp; Compound Authentication</xhtml:strong>:</xhtml:li>
          <xhtml:li>Authentication Silos leverage Dynamic Access Control (DAC) device claims. When accounts are enrolled in a silo, Active Directory automatically issues the <xhtml:code>@Device.ad:silo</xhtml:code> claim during Kerberos authentication. Enabled by Kerberos Flexible Authentication Secure Tunneling (FAST / RFC 6113), the KDC evaluates compound authentication, validating both the user identity and the computer identity simultaneously against conditional Security Descriptor Definition Language (SDDL) rules such as <xhtml:code>O:SYG:SYD:(XA;;CR;;;WD;(@Device.ad:silo == "T0_Silo"))</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Restricted Kerberos TGT Lifetimes</xhtml:strong>:</xhtml:li>
          <xhtml:li>Authentication Policies enforce reduced Kerberos Ticket Granting Ticket (TGT) lifetimes (e.g., 120 minutes / 2 hours) specifically on high-privilege silo accounts, without impacting standard domain users whose default TGT lifetime remains 10 hours. This significantly constrains the window of opportunity for ticket reuse attacks or stolen session ticket exploitation.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Defense-in-Depth Architectural Triad</xhtml:strong>:</xhtml:li>
          <xhtml:li>Authentication Silos form an inseparable architectural defense triad with the <xhtml:strong>Protected Users</xhtml:strong> security group (REQ-ID-005), <xhtml:strong>Kerberos Armoring (FAST)</xhtml:strong> (REQ-DC-013, REQ-PAW-013, REQ-END-013), and <xhtml:strong>Privileged Access Workstations</xhtml:strong> (PAWs). Together, these controls prevent credential dumping, halt NTLM fallback, and enforce strict Tier 0 cryptographic isolation.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy &amp; Active Directory Administrative Center (ADAC) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Enable KDC Claims and Armoring on Domain Controllers via GPO</xhtml:h4>
        <xhtml:p>Before configuring silos, Domain Controllers must be configured to support claims and Kerberos armoring:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Group Policy Management</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\KDC</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>KDC support for claims, compound authentication and Kerberos armoring</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under options, select <xhtml:strong>Supported</xhtml:strong> (or <xhtml:strong>Always provide claims</xhtml:strong>).</xhtml:li>
          <xhtml:li>Save the GPO and run <xhtml:code>gpupdate /force</xhtml:code> on all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Enable Kerberos Client Support on PAWs and Domain Controllers via GPO</xhtml:h4>
        <xhtml:p>All Tier 0 PAWs and Domain Controllers must be configured to assert client claims:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Edit the GPO linked to the <xhtml:strong>Privileged Access Workstations</xhtml:strong> OU and the <xhtml:strong>Domain Controllers</xhtml:strong> OU.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Kerberos</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Kerberos client support for claims, compound authentication and Kerberos armoring</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Save the GPO and run <xhtml:code>gpupdate /force</xhtml:code> on target systems.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Enable Operational Event Logging on Domain Controllers</xhtml:h4>
        <xhtml:p>On each Domain Controller, enable the operational log channel to capture audit events:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open an elevated command prompt on the Domain Controller.</xhtml:li>
          <xhtml:li>Execute:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>wevtutil sl Microsoft-Windows-Authentication/AuthenticationPolicyFailures-DomainController/Operational /e:true</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Create the Authentication Policy in ADAC (Staging / Audit Mode)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>) on a Domain Controller or PAW.</xhtml:li>
          <xhtml:li>In the left navigation pane, switch to the <xhtml:strong>Tree View</xhtml:strong>, expand the domain, and select the <xhtml:strong>Authentication</xhtml:strong> container.</xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Authentication Policies</xhtml:strong>, select <xhtml:strong>New</xhtml:strong>, and click <xhtml:strong>Authentication Policy</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>T0_AuthPol</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Description</xhtml:em>*: <xhtml:code>Authentication Policy for Tier 0 Isolation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>User</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Enforce user ticket lifetime restrictions</xhtml:em>* and enter <xhtml:code>120</xhtml:code> minutes.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>User Allowed To Authenticate From</xhtml:em>
            <xhtml:em>, click </xhtml:em>
            <xhtml:em>Edit</xhtml:em>
            <xhtml:em>, click </xhtml:em>
            <xhtml:em>Add a condition</xhtml:em>*, and specify:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Device</xhtml:code>
            <xhtml:code>ad:silo</xhtml:code>
            <xhtml:code>Equals</xhtml:code>
            <xhtml:code>Value</xhtml:code>
            <xhtml:code>T0_Silo</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Policy setting</xhtml:em>
            <xhtml:em>, leave </xhtml:em>
            <xhtml:em>Audit policy restrictions</xhtml:em>* selected during the initial deployment phase.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Computer</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Enforce computer ticket lifetime restrictions</xhtml:em>* and enter <xhtml:code>120</xhtml:code> minutes.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Service</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Enforce service ticket lifetime restrictions</xhtml:em>* and enter <xhtml:code>120</xhtml:code> minutes.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save the policy.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>5. Create the Authentication Policy Silo in ADAC</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the <xhtml:strong>Authentication</xhtml:strong> container, right-click <xhtml:strong>Authentication Policy Silos</xhtml:strong>, select <xhtml:strong>New</xhtml:strong>, and click <xhtml:strong>Authentication Policy Silo</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>T0_Silo</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Description</xhtml:em>*: <xhtml:code>Authentication Policy Silo for Tier 0 Containment</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Permitted Accounts</xhtml:em>
            <xhtml:em>, click </xhtml:em>
            <xhtml:em>Add</xhtml:em>* to specify:</xhtml:li>
          <xhtml:li>* All Tier 0 Administrator user accounts.</xhtml:li>
          <xhtml:li>* All Tier 0 Privileged Access Workstations (PAWs).</xhtml:li>
          <xhtml:li>* All writable Domain Controllers in the domain.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Authentication Policies</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>User</xhtml:em>*: Select <xhtml:code>T0_AuthPol</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Computer</xhtml:em>*: Select <xhtml:code>T0_AuthPol</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Service</xhtml:em>*: Select <xhtml:code>T0_AuthPol</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Silo setting</xhtml:em>
            <xhtml:em>, select </xhtml:em>
            <xhtml:em>Audit silo policies</xhtml:em>* during initial staging.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to create the silo.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>6. Validate Staging Logs and Switch to Enforced Mode</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>After running the silo in Audit Mode for 14 to 30 days, review Event Viewer on Domain Controllers under:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Applications and Services Logs\Microsoft\Windows\Authentication\AuthenticationPolicyFailures-DomainController\Operational</xhtml:code>
          </xhtml:li>
          <xhtml:li>Confirm that no legitimate administrative workflows generate Event IDs 16867 or 16868.</xhtml:li>
          <xhtml:li>Confirm that all enrolled Tier 0 administrative users are members of the <xhtml:strong>Protected Users</xhtml:strong> group (<xhtml:code>CN=Protected Users,CN=Users,DC=[Domain]</xhtml:code>).</xhtml:li>
          <xhtml:li>Re-open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>Open <xhtml:code>T0_AuthPol</xhtml:code> and change the policy setting to <xhtml:strong>Enforce policy restrictions</xhtml:strong>.</xhtml:li>
          <xhtml:li>Open <xhtml:code>T0_Silo</xhtml:code> and change the silo setting to <xhtml:strong>Enforce the silo policies</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to apply full cryptographic enforcement.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to configure local KDC registry settings, enable the operational event log channel, create the Tier 0 Authentication Policy with device claim restrictions, create the Silo, and enroll Domain Controllers, PAWs, and administrators.</xhtml:p>
        <xhtml:p>By default, the script deploys in <xhtml:strong>Audit Mode</xhtml:strong> to prevent accidental lockouts. Specify the <xhtml:code>-Enforce</xhtml:code> switch parameter once staging and logging validation are complete.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADAuthenticationSilo.ps1">Download Script: Set-ADAuthenticationSilo.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADAuthenticationSilo.ps1
# Description: Configures Active Directory Authentication Policies and Silos for Tier 0 isolation.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [switch]$Enforce,

    [Parameter(Mandatory = $false)]
    [string]$PolicyName = "T0_AuthPol",

    [Parameter(Mandatory = $false)]
    [string]$SiloName = "T0_Silo",

    [Parameter(Mandatory = $false)]
    [string]$UserGroupName = "Grp_Tier0_Admins",

    [Parameter(Mandatory = $false)]
    [string]$ComputerGroupName = "Grp_Tier0_PAWs",

    [Parameter(Mandatory = $false)]
    [int]$UserTGTLifetimeMins = 120
)

Import-Module ActiveDirectory -ErrorAction Stop

Write-Host "Applying hardening requirement: Configure Active Directory Authentication Silos..." -ForegroundColor Cyan

# 1. Validate Domain Functional Level
$domain = Get-ADDomain -ErrorAction Stop
if ($domain.DomainMode -lt [Microsoft.ActiveDirectory.Management.ADDomainMode]::Windows2012R2Domain) {
    Write-Error "Active Directory Domain Functional Level must be Windows Server 2012 R2 or higher. Current DFL: $($domain.DomainMode)"
    return
}

# 2. Configure KDC and Kerberos Client Registry Keys on Local Domain Controller
$kdcRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"
$kerbRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path -Path $kdcRegPath)) {
    New-Item -Path $kdcRegPath -Force | Out-Null
}
# Enable KDC support for claims, compound authentication, and armoring (1 = Supported)
Set-ItemProperty -Path $kdcRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $kdcRegPath -Name "CbacAndArmorLevel" -Value 1 -Type DWord -Force
Write-Host "[+] Local KDC registry configured for claims and Kerberos armoring." -ForegroundColor Green

if (-not (Test-Path -Path $kerbRegPath)) {
    New-Item -Path $kerbRegPath -Force | Out-Null
}
Set-ItemProperty -Path $kerbRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord -Force
Write-Host "[+] Local Kerberos client registry configured for claims and armoring." -ForegroundColor Green

# 3. Enable Operational Event Log Channel on Domain Controller
try {
    $logChannel = "Microsoft-Windows-Authentication/AuthenticationPolicyFailures-DomainController/Operational"
    wevtutil sl $logChannel /e:true 2&gt;$null
    Write-Host "[+] Enabled operational log channel: $($logChannel)" -ForegroundColor Green
} catch {
    Write-Host "[!] Could not configure operational log channel via wevtutil: $($_.Exception.Message)" -ForegroundColor Yellow
}

$enforceMode = $Enforce.IsPresent
$modeDescription = if ($enforceMode) { "Enforced" } else { "Audit Mode (Staging)" }
Write-Host "[*] Configuring Authentication Silo and Policy in mode: $($modeDescription)" -ForegroundColor Cyan

# 4. Construct Device Claims SDDL Condition
# Limits user authentication exclusively to devices belonging to the specified Silo
$deviceConditionSddl = "O:SYG:SYD:(XA;;CR;;;WD;(@Device.ad:silo == `"$SiloName`"))"

# 5. Create or Update the Authentication Policy
$existPolicy = Get-ADAuthenticationPolicy -Filter "Name -eq '$PolicyName'" -ErrorAction SilentlyContinue

if (-not $existPolicy) {
    New-ADAuthenticationPolicy -Name $PolicyName `
        -Description "Authentication Policy for Tier 0 Isolation" `
        -UserTGTLifetimeMins $UserTGTLifetimeMins `
        -UserAllowedToAuthenticateFrom $deviceConditionSddl `
        -Enforce $enforceMode `
        -ProtectedFromAccidentalDeletion $true `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy '$PolicyName' created (Enforce: $($enforceMode), TGT Lifetime: $($UserTGTLifetimeMins)m)." -ForegroundColor Green
} else {
    Set-ADAuthenticationPolicy -Identity $PolicyName `
        -UserTGTLifetimeMins $UserTGTLifetimeMins `
        -UserAllowedToAuthenticateFrom $deviceConditionSddl `
        -Enforce $enforceMode `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy '$PolicyName' updated (Enforce: $($enforceMode), TGT Lifetime: $($UserTGTLifetimeMins)m)." -ForegroundColor Green
}

# 6. Create or Update the Authentication Policy Silo
$existSilo = Get-ADAuthenticationPolicySilo -Filter "Name -eq '$SiloName'" -ErrorAction SilentlyContinue

if (-not $existSilo) {
    New-ADAuthenticationPolicySilo -Name $SiloName `
        -Description "Authentication Policy Silo for Tier 0 Containment" `
        -UserAuthenticationPolicy $PolicyName `
        -ComputerAuthenticationPolicy $PolicyName `
        -ServiceAuthenticationPolicy $PolicyName `
        -Enforce $enforceMode `
        -ProtectedFromAccidentalDeletion $true `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy Silo '$SiloName' created (Enforce: $($enforceMode))." -ForegroundColor Green
} else {
    Set-ADAuthenticationPolicySilo -Identity $SiloName `
        -UserAuthenticationPolicy $PolicyName `
        -ComputerAuthenticationPolicy $PolicyName `
        -ServiceAuthenticationPolicy $PolicyName `
        -Enforce $enforceMode `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy Silo '$SiloName' updated (Enforce: $($enforceMode))." -ForegroundColor Green
}

# 7. Grant Silo Access and Enroll Domain Controllers (Mandatory for T0 Silo)
Write-Host "[*] Enrolling Domain Controllers into silo '$SiloName'..." -ForegroundColor White
$domainControllers = Get-ADDomainController -Filter "IsReadOnly -eq `$false"
foreach ($dc in $domainControllers) {
    $dcDn = $dc.ComputerObjectDN
    Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $dcDn -ErrorAction SilentlyContinue
    Set-ADAccountAuthenticationPolicySilo -Identity $dcDn -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
    Write-Host "    - Enrolled DC: $($dc.HostName)" -ForegroundColor Gray
}

# 8. Grant Silo Access and Enroll Tier 0 Admin Users
$userGroup = Get-ADGroup -Filter "Name -eq '$UserGroupName'" -ErrorAction SilentlyContinue
if ($userGroup) {
    Write-Host "[*] Enrolling members of user group '$UserGroupName'..." -ForegroundColor White
    $adminUsers = Get-ADGroupMember -Identity $userGroup -Recursive | Where-Object { $_.objectClass -eq "user" }
    foreach ($user in $adminUsers) {
        Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $user.distinguishedName -ErrorAction SilentlyContinue
        Set-ADAccountAuthenticationPolicySilo -Identity $user.distinguishedName -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
        Write-Host "    - Enrolled User: $($user.SamAccountName)" -ForegroundColor Gray
    }
} else {
    Write-Host "[-] User group '$UserGroupName' not found in Active Directory. Skipping user enrollment." -ForegroundColor Yellow
}

# 9. Grant Silo Access and Enroll Tier 0 PAW Computers
$compGroup = Get-ADGroup -Filter "Name -eq '$ComputerGroupName'" -ErrorAction SilentlyContinue
if ($compGroup) {
    Write-Host "[*] Enrolling members of computer group '$ComputerGroupName'..." -ForegroundColor White
    $pawComputers = Get-ADGroupMember -Identity $compGroup -Recursive | Where-Object { $_.objectClass -eq "computer" }
    foreach ($comp in $pawComputers) {
        Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $comp.distinguishedName -ErrorAction SilentlyContinue
        Set-ADAccountAuthenticationPolicySilo -Identity $comp.distinguishedName -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
        Write-Host "    - Enrolled Computer: $($comp.SamAccountName)" -ForegroundColor Gray
    }
} else {
    Write-Host "[-] Computer group '$ComputerGroupName' not found in Active Directory. Skipping computer enrollment." -ForegroundColor Yellow
}

# 10. Audit Protected Users Group Membership for Silo Users
Write-Host "[*] Auditing Protected Users membership for Tier 0 silo accounts..." -ForegroundColor White
$protectedUsersGroup = Get-ADGroup -Identity "Protected Users" -ErrorAction SilentlyContinue
if ($protectedUsersGroup) {
    $siloMembers = Get-ADAuthenticationPolicySilo -Identity $SiloName -Properties Members
    $unprotectedCount = 0
    foreach ($memberDn in $siloMembers.Members) {
        $accountObj = Get-ADObject -Identity $memberDn -Properties objectClass, sAMAccountName -ErrorAction SilentlyContinue
        if ($accountObj -and $accountObj.objectClass -eq "user") {
            $isProtected = Get-ADGroupMember -Identity "Protected Users" -Recursive | Where-Object { $_.distinguishedName -eq $memberDn }
            if (-not $isProtected) {
                Write-Host "[!] WARNING: Silo user '$($accountObj.sAMAccountName)' is NOT in Protected Users group! Vulnerable to NTLM bypass." -ForegroundColor Yellow
                $unprotectedCount++
            }
        }
    }
    if ($unprotectedCount -eq 0) {
        Write-Host "[+] All enrolled silo users are members of the Protected Users group." -ForegroundColor Green
    }
}

Write-Host "[+] Authentication Silo membership initialized." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit Authentication Silos, KDC armoring configuration, enforcement states, and Protected Users group membership:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-AuthSiloAuditStatus.ps1">Download Script: Get-AuthSiloAuditStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AuthSiloAuditStatus.ps1
# Description: Queries the active Authentication Silos, verifies KDC claims support, checks enforcement state, and audits Protected Users membership.
# Target Engine: Windows PowerShell 5.1

Import-Module ActiveDirectory -ErrorAction SilentlyContinue

Write-Host "--- Auditing Authentication Silos ---" -ForegroundColor Cyan

$isCompliant = $true

# 1. Audit KDC and Kerberos Client Registry Settings for Claims and Armoring
$kdcRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"
$kerbRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

$kdcArmored = $false
if (Test-Path -Path $kdcRegPath) {
    $kdcEnable = (Get-ItemProperty -Path $kdcRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue).EnableCbacAndArmor
    $kdcLevel = (Get-ItemProperty -Path $kdcRegPath -Name "CbacAndArmorLevel" -ErrorAction SilentlyContinue).CbacAndArmorLevel
    if ($kdcEnable -eq 1 -and ($kdcLevel -ge 1)) {
        $kdcArmored = $true
        Write-Host "[+] Status: Compliant. KDC support for claims and Kerberos armoring is enabled." -ForegroundColor Green
    }
}

if (-not $kdcArmored) {
    Write-Host "VULNERABLE: KDC support for claims, compound authentication, and Kerberos armoring is NOT enabled in registry ($kdcRegPath)." -ForegroundColor Red
    $isCompliant = $false
}

$kerbArmored = $false
if (Test-Path -Path $kerbRegPath) {
    $kerbEnable = (Get-ItemProperty -Path $kerbRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue).EnableCbacAndArmor
    if ($kerbEnable -eq 1) {
        $kerbArmored = $true
        Write-Host "[+] Status: Compliant. Kerberos client support for claims and armoring is enabled." -ForegroundColor Green
    }
}

if (-not $kerbArmored) {
    Write-Host "VULNERABLE: Kerberos client support for claims and armoring is NOT enabled in registry ($kerbRegPath)." -ForegroundColor Red
    $isCompliant = $false
}

# 2. Audit Operational Event Log Channel
try {
    $logChannel = "Microsoft-Windows-Authentication/AuthenticationPolicyFailures-DomainController/Operational"
    $logConfig = Get-WinEvent -ListLog $logChannel -ErrorAction Stop
    if ($logConfig.IsEnabled) {
        Write-Host "[+] Status: Compliant. Operational authentication failure event log channel is enabled." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Operational authentication failure event log channel is disabled: $($logChannel)" -ForegroundColor Red
        $isCompliant = $false
    }
} catch {
    Write-Host "[-] Operational log channel check skipped or unavailable on this node." -ForegroundColor Yellow
}

# 3. Audit Active Directory Authentication Policy Silos
try {
    $silos = Get-ADAuthenticationPolicySilo -Filter * -Properties * -ErrorAction Stop
    if (-not $silos) {
        Write-Host "VULNERABLE: No Active Directory Authentication Policy Silos configured in this domain." -ForegroundColor Red
        $isCompliant = $false
    } else {
        foreach ($silo in $silos) {
            Write-Host "[*] Silo Name: $($silo.Name)" -ForegroundColor Cyan
            Write-Host "    - Description: $($silo.Description)" -ForegroundColor White
            Write-Host "    - Enforced: $($silo.Enforce)" -ForegroundColor White
            Write-Host "    - User Policy: $($silo.UserAuthenticationPolicy)" -ForegroundColor White
            Write-Host "    - Computer Policy: $($silo.ComputerAuthenticationPolicy)" -ForegroundColor White

            if (-not $silo.Enforce) {
                Write-Host "    [!] Silo '$($silo.Name)' is in AUDIT mode (Enforce = False). Verify staging logs before enforcement." -ForegroundColor Yellow
            }

            # Verify associated User Authentication Policy
            if ($silo.UserAuthenticationPolicy) {
                $userPolicy = Get-ADAuthenticationPolicy -Identity $silo.UserAuthenticationPolicy -Properties * -ErrorAction SilentlyContinue
                if ($userPolicy) {
                    Write-Host "    - User TGT Lifetime: $($userPolicy.UserTGTLifetimeMins) minutes" -ForegroundColor White
                    Write-Host "    - Policy Enforced: $($userPolicy.Enforce)" -ForegroundColor White
                    if ($userPolicy.UserTGTLifetimeMins -gt 240) {
                        Write-Host "    [!] Policy TGT lifetime exceeds 240 minutes ($($userPolicy.UserTGTLifetimeMins)m)." -ForegroundColor Yellow
                    }
                }
            }

            # Check Silo Members: DCs must be enrolled in T0 Silo
            if ($silo.Name -like "*T0*" -or $silo.Name -like "*Tier0*") {
                $dcs = Get-ADDomainController -Filter "IsReadOnly -eq `$false" -ErrorAction SilentlyContinue
                $missingDcs = 0
                foreach ($dc in $dcs) {
                    $assignedSilo = (Get-ADAccountAuthenticationPolicySilo -Identity $dc.ComputerObjectDN -ErrorAction SilentlyContinue).AuthenticationPolicySilo
                    if (-not $assignedSilo -or $assignedSilo -ne $silo.DistinguishedName) {
                        $missingDcs++
                    }
                }
                if ($missingDcs -gt 0) {
                    Write-Host "    VULNERABLE: $($missingDcs) writable Domain Controller(s) are NOT assigned to Tier 0 Silo '$($silo.Name)'." -ForegroundColor Red
                    $isCompliant = $false
                } else {
                    Write-Host "    [+] All writable Domain Controllers are assigned to Tier 0 Silo." -ForegroundColor Green
                }
            }

            # Check Silo Members: User accounts must be members of Protected Users group
            $members = $silo.Members
            $unprotectedUsers = 0
            if ($members) {
                foreach ($memberDn in $members) {
                    $memberObj = Get-ADObject -Identity $memberDn -Properties objectClass, sAMAccountName -ErrorAction SilentlyContinue
                    if ($memberObj -and $memberObj.objectClass -eq "user") {
                        $isProtected = Get-ADGroupMember -Identity "Protected Users" -Recursive -ErrorAction SilentlyContinue | Where-Object { $_.distinguishedName -eq $memberDn }
                        if (-not $isProtected) {
                            $unprotectedUsers++
                            Write-Host "    VULNERABLE: Silo user '$($memberObj.sAMAccountName)' is NOT in Protected Users group (NTLM bypass risk)!" -ForegroundColor Red
                        }
                    }
                }
            }
            if ($unprotectedUsers -gt 0) {
                $isCompliant = $false
            }
        }
    }
} catch {
    Write-Host "[-] Could not query Active Directory Authentication Policy Silos: $($_.Exception.Message)" -ForegroundColor Yellow
}

# 4. Final Compliance Verdict
if ($isCompliant) {
    Write-Host "Audit Result: SECURE (Authentication Silos and Policies configured and compliant)" -ForegroundColor Green
} else {
    Write-Host "Audit Result: VULNERABLE (Authentication Silos and Policies missing or non-compliant)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADAuthenticationSilo.ps1
# Description: Configures Active Directory Authentication Policies and Silos for Tier 0 isolation.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [switch]$Enforce,

    [Parameter(Mandatory = $false)]
    [string]$PolicyName = "T0_AuthPol",

    [Parameter(Mandatory = $false)]
    [string]$SiloName = "T0_Silo",

    [Parameter(Mandatory = $false)]
    [string]$UserGroupName = "Grp_Tier0_Admins",

    [Parameter(Mandatory = $false)]
    [string]$ComputerGroupName = "Grp_Tier0_PAWs",

    [Parameter(Mandatory = $false)]
    [int]$UserTGTLifetimeMins = 120
)

Import-Module ActiveDirectory -ErrorAction Stop

Write-Host "Applying hardening requirement: Configure Active Directory Authentication Silos..." -ForegroundColor Cyan

# 1. Validate Domain Functional Level
$domain = Get-ADDomain -ErrorAction Stop
if ($domain.DomainMode -lt [Microsoft.ActiveDirectory.Management.ADDomainMode]::Windows2012R2Domain) {
    Write-Error "Active Directory Domain Functional Level must be Windows Server 2012 R2 or higher. Current DFL: $($domain.DomainMode)"
    return
}

# 2. Configure KDC and Kerberos Client Registry Keys on Local Domain Controller
$kdcRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\KDC\Parameters"
$kerbRegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path -Path $kdcRegPath)) {
    New-Item -Path $kdcRegPath -Force | Out-Null
}
# Enable KDC support for claims, compound authentication, and armoring (1 = Supported)
Set-ItemProperty -Path $kdcRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $kdcRegPath -Name "CbacAndArmorLevel" -Value 1 -Type DWord -Force
Write-Host "[+] Local KDC registry configured for claims and Kerberos armoring." -ForegroundColor Green

if (-not (Test-Path -Path $kerbRegPath)) {
    New-Item -Path $kerbRegPath -Force | Out-Null
}
Set-ItemProperty -Path $kerbRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord -Force
Write-Host "[+] Local Kerberos client registry configured for claims and armoring." -ForegroundColor Green

# 3. Enable Operational Event Log Channel on Domain Controller
try {
    $logChannel = "Microsoft-Windows-Authentication/AuthenticationPolicyFailures-DomainController/Operational"
    wevtutil sl $logChannel /e:true 2&gt;$null
    Write-Host "[+] Enabled operational log channel: $($logChannel)" -ForegroundColor Green
} catch {
    Write-Host "[!] Could not configure operational log channel via wevtutil: $($_.Exception.Message)" -ForegroundColor Yellow
}

$enforceMode = $Enforce.IsPresent
$modeDescription = if ($enforceMode) { "Enforced" } else { "Audit Mode (Staging)" }
Write-Host "[*] Configuring Authentication Silo and Policy in mode: $($modeDescription)" -ForegroundColor Cyan

# 4. Construct Device Claims SDDL Condition
# Limits user authentication exclusively to devices belonging to the specified Silo
$deviceConditionSddl = "O:SYG:SYD:(XA;;CR;;;WD;(@Device.ad:silo == `"$SiloName`"))"

# 5. Create or Update the Authentication Policy
$existPolicy = Get-ADAuthenticationPolicy -Filter "Name -eq '$PolicyName'" -ErrorAction SilentlyContinue

if (-not $existPolicy) {
    New-ADAuthenticationPolicy -Name $PolicyName `
        -Description "Authentication Policy for Tier 0 Isolation" `
        -UserTGTLifetimeMins $UserTGTLifetimeMins `
        -UserAllowedToAuthenticateFrom $deviceConditionSddl `
        -Enforce $enforceMode `
        -ProtectedFromAccidentalDeletion $true `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy '$PolicyName' created (Enforce: $($enforceMode), TGT Lifetime: $($UserTGTLifetimeMins)m)." -ForegroundColor Green
} else {
    Set-ADAuthenticationPolicy -Identity $PolicyName `
        -UserTGTLifetimeMins $UserTGTLifetimeMins `
        -UserAllowedToAuthenticateFrom $deviceConditionSddl `
        -Enforce $enforceMode `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy '$PolicyName' updated (Enforce: $($enforceMode), TGT Lifetime: $($UserTGTLifetimeMins)m)." -ForegroundColor Green
}

# 6. Create or Update the Authentication Policy Silo
$existSilo = Get-ADAuthenticationPolicySilo -Filter "Name -eq '$SiloName'" -ErrorAction SilentlyContinue

if (-not $existSilo) {
    New-ADAuthenticationPolicySilo -Name $SiloName `
        -Description "Authentication Policy Silo for Tier 0 Containment" `
        -UserAuthenticationPolicy $PolicyName `
        -ComputerAuthenticationPolicy $PolicyName `
        -ServiceAuthenticationPolicy $PolicyName `
        -Enforce $enforceMode `
        -ProtectedFromAccidentalDeletion $true `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy Silo '$SiloName' created (Enforce: $($enforceMode))." -ForegroundColor Green
} else {
    Set-ADAuthenticationPolicySilo -Identity $SiloName `
        -UserAuthenticationPolicy $PolicyName `
        -ComputerAuthenticationPolicy $PolicyName `
        -ServiceAuthenticationPolicy $PolicyName `
        -Enforce $enforceMode `
        -ErrorAction Stop
    Write-Host "[+] Authentication Policy Silo '$SiloName' updated (Enforce: $($enforceMode))." -ForegroundColor Green
}

# 7. Grant Silo Access and Enroll Domain Controllers (Mandatory for T0 Silo)
Write-Host "[*] Enrolling Domain Controllers into silo '$SiloName'..." -ForegroundColor White
$domainControllers = Get-ADDomainController -Filter "IsReadOnly -eq `$false"
foreach ($dc in $domainControllers) {
    $dcDn = $dc.ComputerObjectDN
    Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $dcDn -ErrorAction SilentlyContinue
    Set-ADAccountAuthenticationPolicySilo -Identity $dcDn -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
    Write-Host "    - Enrolled DC: $($dc.HostName)" -ForegroundColor Gray
}

# 8. Grant Silo Access and Enroll Tier 0 Admin Users
$userGroup = Get-ADGroup -Filter "Name -eq '$UserGroupName'" -ErrorAction SilentlyContinue
if ($userGroup) {
    Write-Host "[*] Enrolling members of user group '$UserGroupName'..." -ForegroundColor White
    $adminUsers = Get-ADGroupMember -Identity $userGroup -Recursive | Where-Object { $_.objectClass -eq "user" }
    foreach ($user in $adminUsers) {
        Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $user.distinguishedName -ErrorAction SilentlyContinue
        Set-ADAccountAuthenticationPolicySilo -Identity $user.distinguishedName -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
        Write-Host "    - Enrolled User: $($user.SamAccountName)" -ForegroundColor Gray
    }
} else {
    Write-Host "[-] User group '$UserGroupName' not found in Active Directory. Skipping user enrollment." -ForegroundColor Yellow
}

# 9. Grant Silo Access and Enroll Tier 0 PAW Computers
$compGroup = Get-ADGroup -Filter "Name -eq '$ComputerGroupName'" -ErrorAction SilentlyContinue
if ($compGroup) {
    Write-Host "[*] Enrolling members of computer group '$ComputerGroupName'..." -ForegroundColor White
    $pawComputers = Get-ADGroupMember -Identity $compGroup -Recursive | Where-Object { $_.objectClass -eq "computer" }
    foreach ($comp in $pawComputers) {
        Grant-ADAuthenticationPolicySiloAccess -Identity $SiloName -Account $comp.distinguishedName -ErrorAction SilentlyContinue
        Set-ADAccountAuthenticationPolicySilo -Identity $comp.distinguishedName -AuthenticationPolicySilo $SiloName -ErrorAction SilentlyContinue
        Write-Host "    - Enrolled Computer: $($comp.SamAccountName)" -ForegroundColor Gray
    }
} else {
    Write-Host "[-] Computer group '$ComputerGroupName' not found in Active Directory. Skipping computer enrollment." -ForegroundColor Yellow
}

# 10. Audit Protected Users Group Membership for Silo Users
Write-Host "[*] Auditing Protected Users membership for Tier 0 silo accounts..." -ForegroundColor White
$protectedUsersGroup = Get-ADGroup -Identity "Protected Users" -ErrorAction SilentlyContinue
if ($protectedUsersGroup) {
    $siloMembers = Get-ADAuthenticationPolicySilo -Identity $SiloName -Properties Members
    $unprotectedCount = 0
    foreach ($memberDn in $siloMembers.Members) {
        $accountObj = Get-ADObject -Identity $memberDn -Properties objectClass, sAMAccountName -ErrorAction SilentlyContinue
        if ($accountObj -and $accountObj.objectClass -eq "user") {
            $isProtected = Get-ADGroupMember -Identity "Protected Users" -Recursive | Where-Object { $_.distinguishedName -eq $memberDn }
            if (-not $isProtected) {
                Write-Host "[!] WARNING: Silo user '$($accountObj.sAMAccountName)' is NOT in Protected Users group! Vulnerable to NTLM bypass." -ForegroundColor Yellow
                $unprotectedCount++
            }
        }
    }
    if ($unprotectedCount -eq 0) {
        Write-Host "[+] All enrolled silo users are members of the Protected Users group." -ForegroundColor Green
    }
}

Write-Host "[+] Authentication Silo membership initialized." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3012" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-013" severity="medium" weight="10.0" selected="false">
      <title>[REQ-ID-013] Clean Up adminCount Attribute Orphans</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Identity Management</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/cleanup-admincount-orphans.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In Active Directory, when an account is added to a protected group (such as <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Schema Admins</xhtml:code>, or <xhtml:code>Account Operators</xhtml:code>), a forest-wide background thread (the <xhtml:code>AdminSDHolder</xhtml:code> task, running on the Domain Controller holding the PDC Emulator role) automatically sets the account's <xhtml:code>adminCount</xhtml:code> attribute to <xhtml:code>1</xhtml:code> and disables security descriptor inheritance. This is done to ensure the account only inherits permissions defined by the secure <xhtml:code>adminSDHolder</xhtml:code> template rather than any insecure permissions on the parent Organizational Unit (OU).</xhtml:p>
        <xhtml:p>A common myth is that Active Directory uses the <xhtml:code>adminCount</xhtml:code> attribute to determine which accounts are protected. In reality, the <xhtml:code>AdminSDHolder</xhtml:code> background task evaluates group membership (direct or nested association with a protected group) to trigger protection, not <xhtml:code>adminCount</xhtml:code>. The <xhtml:code>adminCount=1</xhtml:code> attribute is merely a metadata flag stamped by the task.</xhtml:p>
        <xhtml:p>However, if that user is later removed from the protected group: 1. <xhtml:strong>adminCount Remains Active</xhtml:strong>: Active Directory does not automatically reset the <xhtml:code>adminCount</xhtml:code> attribute to <xhtml:code>0</xhtml:code> or empty, nor does it re-enable security descriptor inheritance on the user object. Although the <xhtml:code>AdminSDHolder</xhtml:code> task stops protecting the object (it no longer overwrites its DACL), inheritance remains permanently disabled. 2. <xhtml:strong>Leaves Account Insecurely Unmanaged</xhtml:strong>: The user object remains orphaned, with inheritance permanently disabled. This blocks future legitimate GPO-based permission updates and can allow persistent, hidden permissions (backdoors) on the object to remain unmitigated. 3. <xhtml:strong>Breaks Management Consistency</xhtml:strong>: Security administrators auditing protected accounts will see false positives, as accounts appear to have administrative attributes when they do not have administrative group memberships.</xhtml:p>
        <xhtml:p>Auditing and resetting these orphan accounts restores proper security inheritance and cleans up directory metadata.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Center (ADAC) Manual Modification</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>) on a Domain Controller.</xhtml:li>
          <xhtml:li>Navigate to your domain and locate the target orphan user account.</xhtml:li>
          <xhtml:li>Right-click the user account and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Attribute Editor</xhtml:strong> (ensure Advanced features are active).</xhtml:li>
          <xhtml:li>Locate the <xhtml:strong>adminCount</xhtml:strong> attribute and click <xhtml:strong>Clear</xhtml:strong> or set the value to <xhtml:code>&lt;not set&gt;</xhtml:code>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Security</xhtml:strong> tab, click <xhtml:strong>Advanced</xhtml:strong>, and click <xhtml:strong>Enable Inheritance</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save and commit changes.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to automatically identify all user accounts with <xhtml:code>adminCount=1</xhtml:code> that are no longer members of any protected AD group, reset the attribute, and re-enable security inheritance.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Cleanup-AdminCountOrphans.ps1">Download Script: Cleanup-AdminCountOrphans.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Cleanup-AdminCountOrphans.ps1
# Description: Resets adminCount and re-enables inheritance on user accounts that are no longer in protected groups.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Clean Up adminCount Attribute Orphans..." -ForegroundColor Cyan

# Define the list of built-in protected AD groups (sAMAccountNames)
$ProtectedGroups = @(
    "Administrators",
    "Domain Admins",
    "Enterprise Admins",
    "Schema Admins",
    "Account Operators",
    "Backup Operators",
    "Print Operators",
    "Server Operators",
    "Cert Publishers",
    "Group Policy Creator Owners"
)

# Fetch all user objects with adminCount set to 1
Write-Host "Scanning domain for accounts with adminCount = 1..." -ForegroundColor White
$Orphans = Get-ADUser -Filter "adminCount -eq 1" -Properties MemberOf, adminCount

$CleanedCount = 0

foreach ($User in $Orphans) {
    $IsStillProtected = $false
    
    # Check if the user is currently in any of the protected groups
    foreach ($Group in $ProtectedGroups) {
        $GroupObj = Get-ADGroup -Filter "Name -eq '$Group'" -ErrorAction SilentlyContinue
        if ($null -ne $GroupObj) {
            # Check membership
            $IsMember = Get-ADGroupMember -Identity $GroupObj -Recursive | Where-Object { $_.distinguishedName -eq $User.distinguishedName }
            if ($null -ne $IsMember) {
                $IsStillProtected = $true
                break
            }
        }
    }
    
    # If the user is no longer in a protected group, perform cleanup
    if (-not $IsStillProtected) {
        Write-Host "[-] Found orphan account: $($User.SamAccountName)" -ForegroundColor Yellow
        
        # 1. Clear the adminCount attribute
        Set-ADUser -Identity $User.distinguishedName -Clear "adminCount" -ErrorAction Stop
        
        # 2. Re-enable ACL inheritance on the object
        $UserDN = $User.distinguishedName
        $AclPath = "AD:\$($UserDN)"
        $Acl = Get-Acl -Path $AclPath
        
        if ($Acl.AreAccessRulesProtected) {
            # Disable protection, copying existing rules as inherited
            $Acl.SetAccessRuleProtection($false, $true)
            Set-Acl -Path $AclPath -AclObject $Acl -ErrorAction Stop
            Write-Host "    - Reset adminCount and enabled security inheritance." -ForegroundColor Green
        } else {
            Write-Host "    - Reset adminCount (security inheritance was already enabled)." -ForegroundColor Green
        }
        
        $CleanedCount++
    }
}

Write-Host "[+] Cleanup complete. Total orphan accounts remediated: $($CleanedCount)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit and list orphan accounts without making changes:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AdminCountOrphansAudit.ps1">Download Script: Get-AdminCountOrphansAudit.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AdminCountOrphansAudit.ps1
# Description: Scans the domain and prints all orphan adminCount accounts.

Import-Module ActiveDirectory

Write-Host "--- Auditing adminCount Orphans ---" -ForegroundColor Cyan

$ProtectedGroups = @("Administrators","Domain Admins","Enterprise Admins","Schema Admins","Account Operators","Backup Operators","Print Operators","Server Operators")
$Users = Get-ADUser -Filter "adminCount -eq 1"

$OrphanCount = 0

foreach ($U in $Users) {
    $Member = $false
    foreach ($Grp in $ProtectedGroups) {
        $GrpObj = Get-ADGroup -Filter "Name -eq '$Grp'"
        if ($GrpObj) {
            $Check = Get-ADGroupMember -Identity $GrpObj -Recursive | Where-Object { $_.distinguishedName -eq $U.distinguishedName }
            if ($Check) {
                $Member = $true
                break
            }
        }
    }
    
    if (-not $Member) {
        Write-Host "[!] Orphan: $($U.SamAccountName) has adminCount=1 but is not in protected groups." -ForegroundColor Yellow
        $OrphanCount++
    }
}

Write-Host "[*] Total adminCount orphans detected: $($OrphanCount)." -ForegroundColor White</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Cleanup-AdminCountOrphans.ps1
# Description: Resets adminCount and re-enables inheritance on user accounts that are no longer in protected groups.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Clean Up adminCount Attribute Orphans..." -ForegroundColor Cyan

# Define the list of built-in protected AD groups (sAMAccountNames)
$ProtectedGroups = @(
    "Administrators",
    "Domain Admins",
    "Enterprise Admins",
    "Schema Admins",
    "Account Operators",
    "Backup Operators",
    "Print Operators",
    "Server Operators",
    "Cert Publishers",
    "Group Policy Creator Owners"
)

# Fetch all user objects with adminCount set to 1
Write-Host "Scanning domain for accounts with adminCount = 1..." -ForegroundColor White
$Orphans = Get-ADUser -Filter "adminCount -eq 1" -Properties MemberOf, adminCount

$CleanedCount = 0

foreach ($User in $Orphans) {
    $IsStillProtected = $false
    
    # Check if the user is currently in any of the protected groups
    foreach ($Group in $ProtectedGroups) {
        $GroupObj = Get-ADGroup -Filter "Name -eq '$Group'" -ErrorAction SilentlyContinue
        if ($null -ne $GroupObj) {
            # Check membership
            $IsMember = Get-ADGroupMember -Identity $GroupObj -Recursive | Where-Object { $_.distinguishedName -eq $User.distinguishedName }
            if ($null -ne $IsMember) {
                $IsStillProtected = $true
                break
            }
        }
    }
    
    # If the user is no longer in a protected group, perform cleanup
    if (-not $IsStillProtected) {
        Write-Host "[-] Found orphan account: $($User.SamAccountName)" -ForegroundColor Yellow
        
        # 1. Clear the adminCount attribute
        Set-ADUser -Identity $User.distinguishedName -Clear "adminCount" -ErrorAction Stop
        
        # 2. Re-enable ACL inheritance on the object
        $UserDN = $User.distinguishedName
        $AclPath = "AD:\$($UserDN)"
        $Acl = Get-Acl -Path $AclPath
        
        if ($Acl.AreAccessRulesProtected) {
            # Disable protection, copying existing rules as inherited
            $Acl.SetAccessRuleProtection($false, $true)
            Set-Acl -Path $AclPath -AclObject $Acl -ErrorAction Stop
            Write-Host "    - Reset adminCount and enabled security inheritance." -ForegroundColor Green
        } else {
            Write-Host "    - Reset adminCount (security inheritance was already enabled)." -ForegroundColor Green
        }
        
        $CleanedCount++
    }
}

Write-Host "[+] Cleanup complete. Total orphan accounts remediated: $($CleanedCount)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3013" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-014" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-014] Renew KDS Root Keys and gMSA Secrets</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Group Managed Service Accounts (gMSAs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/renew-kds-keys-gmsa-secrets.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Group Managed Service Accounts (gMSAs) offer secure, automated password management (complex 120-character passwords rotated every 30 days) for services running on domain member systems. The passwords for these accounts are generated by the Key Distribution Service (KDS) running on Domain Controllers.</xhtml:p>
        <xhtml:p>However, the password generation algorithm relies on KDS root keys stored in the AD Configuration partition.</xhtml:p>
        <xhtml:p>If an attacker compromises or steals the Active Directory database (e.g., via NTDS.dit exfiltration), they obtain the active KDS root keys. Using these keys, the attacker can recalculate the passwords for any gMSA at any time, establishing an invisible, persistent backdoor to any service running under a gMSA.</xhtml:p>
        <xhtml:p>Therefore: 1. <xhtml:strong>Interrupts Attacker Persistence</xhtml:strong>: Generating a new KDS root key and forcing all gMSA accounts to rotate their passwords invalidates any previously compromised password generation seeds. 2. <xhtml:strong>Harden Service Isolation</xhtml:strong>: Ensures that service account security boundaries remain intact post-remediation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory PowerShell Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Because KDS keys and gMSAs do not have standard GPO management interfaces, the creation of root keys and service account password rotation must be executed via PowerShell.</xhtml:p>
        <xhtml:h4>1. Generate a New KDS Root Key</xhtml:h4>
        <xhtml:p>Open an elevated PowerShell console on the PDC Emulator Domain Controller and run:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/New-KdsKey.ps1">Download Script: New-KdsKey.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># New-KdsKey.ps1
# Description: Generates a new KDS Root Key.

Import-Module Kds

Write-Host "Creating new KDS Root Key..." -ForegroundColor Cyan

# Create new KDS key effective immediately (backdated by 10 hours to bypass replication delay)
$NewKey = Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)) -ErrorAction Stop

if ($null -ne $NewKey) {
    Write-Host "[+] New KDS Root Key created successfully. Key ID: $NewKey" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Force gMSA Password Rotation</xhtml:h4>
        <xhtml:p>Once the new root key is active, force password rotation for all gMSAs:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Rotate-gMSAPasswords.ps1">Download Script: Rotate-gMSAPasswords.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Rotate-gMSAPasswords.ps1
# Description: Forces password rotation for all gMSAs.

Import-Module ActiveDirectory

Write-Host "Locating all gMSAs in the domain..." -ForegroundColor Cyan

$gMSAs = Get-ADServiceAccount -Filter "ObjectClass -eq 'msDS-GroupManagedServiceAccount'"

if ($gMSAs) {
    foreach ($Acct in $gMSAs) {
        Write-Host "[*] Rotating password for gMSA: $($Acct.Name)..." -ForegroundColor White
        
        # Reset password (forces rotation on the next request by the host computer)
        Reset-ADServiceAccountPassword -Identity $Acct.DistinguishedName -ErrorAction Stop
        
        Write-Host "[+] Password rotated successfully for $($Acct.Name)." -ForegroundColor Green
    }
} else {
    Write-Host "[-] No Group Managed Service Accounts found." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Auditing Status</xhtml:h3>
        <xhtml:p>Use this PowerShell script to audit current KDS root keys and gMSA replication status.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-KdsAndGmsaAudit.ps1">Download Script: Get-KdsAndGmsaAudit.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KdsAndGmsaAudit.ps1
# Description: Audits active KDS root keys and checks gMSA accounts.

Import-Module ActiveDirectory
Import-Module Kds

Write-Host "--- Auditing KDS Root Keys ---" -ForegroundColor Cyan

$KdsKeys = Get-KdsRootKey -ErrorAction SilentlyContinue

if ($KdsKeys) {
    foreach ($Key in $KdsKeys) {
        Write-Host "[+] KDS Key ID:     $($Key.KeyId)" -ForegroundColor Green
        Write-Host "    - Created:       $($Key.CreateTime)" -ForegroundColor White
        Write-Host "    - Effective:     $($Key.EffectiveTime)" -ForegroundColor White
    }
} else {
    Write-Host "[-] No KDS Root Keys found in the forest." -ForegroundColor Red
}

Write-Host "--- Auditing gMSA Accounts ---" -ForegroundColor Cyan

$Accounts = Get-ADServiceAccount -Filter * -Properties msDS-ManagedPasswordInterval, msDS-HostSecurityGroupsScope

if ($Accounts) {
    foreach ($Acct in $Accounts) {
        Write-Host "[*] gMSA: $($Acct.Name)" -ForegroundColor White
        Write-Host "    - Rotation Interval: $($Acct.'msDS-ManagedPasswordInterval') days" -ForegroundColor Gray
    }
} else {
    Write-Host "[-] No service accounts found." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># New-KdsKey.ps1
# Description: Generates a new KDS Root Key.

Import-Module Kds

Write-Host "Creating new KDS Root Key..." -ForegroundColor Cyan

# Create new KDS key effective immediately (backdated by 10 hours to bypass replication delay)
$NewKey = Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)) -ErrorAction Stop

if ($null -ne $NewKey) {
    Write-Host "[+] New KDS Root Key created successfully. Key ID: $NewKey" -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3014" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-015" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-015] Harden Active Directory Certificate Services (ADCS) and PKI</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Member Servers (Certification Authorities), Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/harden-adcs-pki.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory Certificate Services (ADCS) is a built-in Public Key Infrastructure (PKI) solution widely used for issuing certificates for computer and user authentication. However, misconfigured certificate templates, weak mapping policies, and unhardened CA web endpoints present severe privilege escalation vectors (collectively referred to as ESC1 through ESC17).</xhtml:p>
        <xhtml:p>Key vulnerabilities include: 1. <xhtml:strong>ESC1 (Enrollee Supplies Subject / SAN Exploitation)</xhtml:strong>: If a certificate template allows the client requesting the certificate to supply the subject name (Subject Alternative Name - SAN) in the enrollment request, and that template allows client authentication, any unprivileged domain user can request a certificate in the name of a Domain Administrator or Domain Controller. Upon receiving the certificate, the attacker can authenticate as that administrator, resulting in instant forest compromise. 2. <xhtml:strong>ESC4 (Template ACL Misconfiguration)</xhtml:strong>: If unprivileged or Tier 1 identities possess write permissions (<xhtml:code>GenericAll</xhtml:code>, <xhtml:code>GenericWrite</xhtml:code>, or <xhtml:code>WriteDacl</xhtml:code>) over a certificate template object in the Active Directory Configuration partition, an attacker can modify the template parameters to enable SAN specification and client authentication (converting it to ESC1), enroll for an administrative certificate, and then restore the original configuration. 3. <xhtml:strong>ESC8 (IIS Web Enrollment NTLM Relay)</xhtml:strong>: The default ADCS HTTP Web Enrollment pages (<xhtml:code>/certsrv</xhtml:code>) do not enforce HTTPS and support NTLM authentication without protection. Attackers can coerce NTLM authentication from a Domain Controller (e.g., using RPC coercion or WebDAV) and relay that authentication to the CA web enrollment endpoint to request a DC certificate, taking over the domain. 4. <xhtml:strong>ESC9 / ESC10 (Weak Certificate Mapping &amp; UPN Swaps)</xhtml:strong>: When weak certificate mapping is permitted (or without strong object SID binding), attackers with write permissions over an account's <xhtml:code>userPrincipalName</xhtml:code> or <xhtml:code>dNSHostName</xhtml:code> can compromise targets via certificate mapping mismatches. 5. <xhtml:strong>ESC1-CMC (KB5014754 Bypass via CMC `id-cmc-addExtensions`)</xhtml:strong>: On patched CAs where PKINIT binds certificates using the <xhtml:code>szOID_NTDS_CA_SECURITY_EXT</xhtml:code> extension, attackers may attempt to embed arbitrary object SIDs into certificate requests via CMC request extensions. Enforcing strict issuance requirements (CA administrator approval) on sensitive authentication templates and keeping CA binaries fully updated neutralizes this bypass.</xhtml:p>
        <xhtml:p>Hardening ADCS templates, enforcing strong certificate binding, and securing endpoints is critical to protect the Tier 0 boundary.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Certificate Templates Console &amp; Registry Configuration</xhtml:h3>
        <xhtml:h4>1. Mitigate ESC1 (Disable Enrollee Supplies Subject)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Certificate Templates Console</xhtml:strong> (<xhtml:code>certtmpl.msc</xhtml:code>) on the CA server or a management host.</xhtml:li>
          <xhtml:li>Locate the active templates used for authentication (e.g., <xhtml:code>User</xhtml:code>, <xhtml:code>Computer</xhtml:code>, or custom templates).</xhtml:li>
          <xhtml:li>Right-click the template and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Subject Name</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Ensure the option <xhtml:strong>Build from this Active Directory information</xhtml:strong> is selected.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do NOT select</xhtml:strong> the option <xhtml:strong>Supply in the request</xhtml:strong>. If a template <xhtml:em>must</xhtml:em> allow user-supplied subjects (e.g., web server SSL templates), ensure that <xhtml:strong>Client Authentication</xhtml:strong> is <xhtml:em>not</xhtml:em> present in the Extended Key Usage (EKU) list, and enforce manager approval (see below).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Enforce Manager Approval on Sensitive Templates (Mitigates ESC1-CMC)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the template properties, select the <xhtml:strong>Issuance Requirements</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Check the box for <xhtml:strong>CA administrator approval</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Require the following for enrollment</xhtml:strong>, set the authorized signatures to <xhtml:code>1</xhtml:code> if an enrollment agent is required.</xhtml:li>
          <xhtml:li>Save the template.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Restrict Certificate Template ACLs (Mitigate ESC4)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the <xhtml:strong>Certificate Templates Console</xhtml:strong>, right-click the template and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>Security</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Verify that only <xhtml:strong>Domain Admins</xhtml:strong>, <xhtml:strong>Enterprise Admins</xhtml:strong>, and <xhtml:strong>SYSTEM</xhtml:strong> hold <xhtml:strong>Full Control</xhtml:strong>, <xhtml:strong>Write</xhtml:strong>, or <xhtml:strong>Write Owner/DACL</xhtml:strong> permissions.</xhtml:li>
          <xhtml:li>Remove any write permissions assigned to <xhtml:code>Authenticated Users</xhtml:code>, <xhtml:code>Domain Users</xhtml:code>, or delegated non-Tier 0 groups.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Disable or Secure HTTP Web Enrollment (Mitigate ESC8)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Log on to the CA server hosting the Web Enrollment role.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Internet Information Services (IIS) Manager</xhtml:strong> (<xhtml:code>inetmgr.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>In the left tree view, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Sites\Default Web Site\CertSrv</xhtml:code>
          </xhtml:li>
          <xhtml:li>In the middle pane, double-click <xhtml:strong>Authentication</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Windows Authentication</xhtml:strong> and click <xhtml:strong>Advanced Settings</xhtml:strong> in the right pane.</xhtml:li>
          <xhtml:li>Set <xhtml:strong>Extended Protection</xhtml:strong> to <xhtml:strong>Required</xhtml:strong> (or <xhtml:strong>Accept</xhtml:strong>).</xhtml:li>
          <xhtml:li>Ensure that the <xhtml:strong>Default Web Site</xhtml:strong> binds exclusively to HTTPS (port 443) and redirect all HTTP traffic to HTTPS.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>Ideally, if Web Enrollment is not required, uninstall the "Active Directory Certificate Services Web Enrollment" role entirely via Server Manager.*</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>5. Enforce Strong Certificate Binding on Domain Controllers (Mitigates ESC9/ESC10)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>On all Domain Controllers, open the Registry Editor (<xhtml:code>regedit.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Services\Kdc</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create or set the DWORD value:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>StrongCertificateBindingEnforcement</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code> (Full Enforcement Mode)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to audit active certificate templates for vulnerable configurations (ESC1).</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-ADCSTemplateAudit.ps1">Download Script: Get-ADCSTemplateAudit.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-ADCSTemplateAudit.ps1
# Description: Audits Active Directory certificate templates for SAN and authentication misconfigurations.

Import-Module ActiveDirectory

Write-Host "--- Auditing ADCS Certificate Templates ---" -ForegroundColor Cyan

$ConfigDN = (Get-ADRootDSE).configurationNamingContext
$TemplatesPath = "LDAP://CN=Certificate Templates,CN=Public Key Services,CN=Services,$($ConfigDN)"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$TemplatesPath)
$Searcher.Filter = "(objectClass=pkipastructure)"
$Templates = $Searcher.FindAll()

$VulnerableCount = 0

foreach ($Result in $Templates) {
    $Template = $Result.GetDirectoryEntry()
    $TemplateName = $Template.cn.Value
    
    # Check if enrollee supplies subject name (SAN flag: 0x00010000)
    $NameFlags = $Template.'msPKI-Certificate-Name-Flag'.Value
    $SuppliesSubject = ($NameFlags -band 0x00010000) -eq 0x00010000
    
    # Check if template is used for Client Authentication (EKU OID: 1.3.6.1.5.5.7.3.2)
    $EkUs = $Template.'pKIExtendedKeyUsage'.Value
    $AllowsClientAuth = $false
    foreach ($Eku in $EkUs) {
        if ($Eku -eq "1.3.6.1.5.5.7.3.2" -or $Eku -eq "1.3.6.1.4.1.311.20.2.2") { # Client Auth or Smartcard Logon
            $AllowsClientAuth = $true
        }
    }
    
    # Check if manager approval is required (Enrollment flag: 0x00000002)
    $EnrollFlags = $Template.'msPKI-Enrollment-Flag'.Value
    $RequiresApproval = ($EnrollFlags -band 0x00000002) -eq 0x00000002

    if ($SuppliesSubject -and $AllowsClientAuth -and -not $RequiresApproval) {
        Write-Host "[!] VULNERABLE TEMPLATE DETECTED (ESC1): $TemplateName" -ForegroundColor Red
        Write-Host "    - Allows Client Authentication" -ForegroundColor White
        Write-Host "    - Enrollee supplies Subject/SAN" -ForegroundColor White
        Write-Host "    - Requires NO Manager Approval" -ForegroundColor White
        $VulnerableCount++
    }
}

if ($VulnerableCount -eq 0) {
    Write-Host "[+] No vulnerable ESC1 certificate templates found." -ForegroundColor Green
} else {
    Write-Host "[-] Action Required: Resolve the above vulnerable templates immediately." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3015" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-016" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-016] Configure Logon Screen and Credentials Delegation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/configure-credential-delegation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Securing interactive logons and connection pathways is critical to preventing identity leaks, unauthorized physical user identification, and credential theft during remote administration:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Logon Screen Reconnaissance</xhtml:strong>: Allowing the local login screen to enumerate local and domain users exposes valid usernames to physical shoulder-surfers or unauthorized operators. Disabling local user enumeration hides username lists at logon.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>CredSSP Vulnerabilities (CVE-2018-0886)</xhtml:strong>: The Credential Security Support Provider protocol (CredSSP) had a logical remote code execution flaw. Enforcing Encryption Oracle Remediation in updated mode blocks connections from unpatched clients and servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Delegated Credential Extraction</xhtml:strong>: When users connect to remote hosts, delegating exportable credentials exposes their authentication materials in remote LSASS memory. Forcing the delegation of non-exportable credentials ensures authentication materials cannot be exported by administrative attackers on the remote system.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Disable Logon Screen Username Enumeration</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to your computer OUs (e.g., <xhtml:code>GPO_Computer_Hardening_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Logon</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Enumerate local users on domain-joined computers</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Disabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure CredSSP and Credentials Delegation</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Credentials Delegation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Encryption Oracle Remediation</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>, and select <xhtml:strong>Force Updated Clients</xhtml:strong> in the options dropdown. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Remote host allows delegation of non-exportable credentials</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to apply logon screen and delegation settings to the registry.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-CredentialDelegationAndLogon.ps1">Download Script: Configure-CredentialDelegationAndLogon.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-CredentialDelegationAndLogon.ps1
# Description: Hardens logon screen user enumeration, CredSSP encryption oracle remediation, and remote host non-exportable credentials delegation.

Write-Host "Applying logon screen and credentials delegation registry controls..." -ForegroundColor Cyan

# 1. Disable Logon Screen User Enumeration
$SystemPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}
Set-ItemProperty -Path $SystemPath -Name "EnumerateLocalUsers" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Logon screen local user enumeration disabled." -ForegroundColor Green

# 2. Enforce CredSSP Encryption Oracle Remediation
$CredSspPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters"
if (-not (Test-Path $CredSspPath)) {
    New-Item -Path $CredSspPath -Force | Out-Null
}
Set-ItemProperty -Path $CredSspPath -Name "AllowEncryptionOracle" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] CredSSP Encryption Oracle Remediation configured to Force Updated Clients." -ForegroundColor Green

# 3. Remote Host Allows Delegation of Non-Exportable Credentials
$DelegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation"
if (-not (Test-Path $DelegPath)) {
    New-Item -Path $DelegPath -Force | Out-Null
}
Set-ItemProperty -Path $DelegPath -Name "AllowProtectedCreds" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Delegation of non-exportable credentials enabled." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit these logon screen and delegation settings:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-CredentialDelegationAndLogonStatus.ps1">Download Script: Get-CredentialDelegationAndLogonStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-CredentialDelegationAndLogonStatus.ps1
# Description: Audits registry configuration of user enumeration, CredSSP, and delegation settings.

Write-Host "--- Auditing Credentials Delegation and Logon Settings ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to check registry settings
function Confirm-RegValue ($Path, $Name, $Expected) {
    if (Test-Path $Path) {
        $Reg = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue
        $Val = $Reg.$Name
        if ($Val -eq $Expected) {
            Write-Host "  [+] Path $($Path) | $($Name): $Val (Expected: $Expected)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: Path $($Path) | $($Name): $Val (Expected: $Expected)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] NOT FOUND: Path $($Path) (Expected: $Name = $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# 1. User Enumeration
Confirm-RegValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "EnumerateLocalUsers" 0

# 2. CredSSP AllowEncryptionOracle
Confirm-RegValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" "AllowEncryptionOracle" 0

# 3. Protected Credentials Delegation
Confirm-RegValue "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" "AllowProtectedCreds" 1

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-CredentialDelegationAndLogon.ps1
# Description: Hardens logon screen user enumeration, CredSSP encryption oracle remediation, and remote host non-exportable credentials delegation.

Write-Host "Applying logon screen and credentials delegation registry controls..." -ForegroundColor Cyan

# 1. Disable Logon Screen User Enumeration
$SystemPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}
Set-ItemProperty -Path $SystemPath -Name "EnumerateLocalUsers" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Logon screen local user enumeration disabled." -ForegroundColor Green

# 2. Enforce CredSSP Encryption Oracle Remediation
$CredSspPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters"
if (-not (Test-Path $CredSspPath)) {
    New-Item -Path $CredSspPath -Force | Out-Null
}
Set-ItemProperty -Path $CredSspPath -Name "AllowEncryptionOracle" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] CredSSP Encryption Oracle Remediation configured to Force Updated Clients." -ForegroundColor Green

# 3. Remote Host Allows Delegation of Non-Exportable Credentials
$DelegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation"
if (-not (Test-Path $DelegPath)) {
    New-Item -Path $DelegPath -Force | Out-Null
}
Set-ItemProperty -Path $DelegPath -Name "AllowProtectedCreds" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Delegation of non-exportable credentials enabled." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3016" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-017" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-017] Disable Machine Account Quota</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Domain Environment</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/disable-machine-account-quota.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>By default, Active Directory sets the domain-level attribute <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> to <xhtml:strong>10</xhtml:strong> on the domain head (<xhtml:code>DC=domain,DC=com</xhtml:code>) and assigns the <xhtml:code>SeMachineAccountPrivilege</xhtml:code> ("Add workstations to domain") User Right to the <xhtml:code>Authenticated Users</xhtml:code> group. This default configuration allows any standard user, compromised domain identity, or unprivileged service account to introduce up to 10 computer objects into the directory.</xhtml:p>
        <xhtml:p>Active Directory governs computer creation through two distinct mechanisms: 1. <xhtml:strong>The `ms-DS-MachineAccountQuota` Domain Attribute</xhtml:strong>: Enforced during direct LDAP/LDAPS operations. Even if local or GPO user rights are restricted, an attacker communicating over LDAP can create computer objects as long as <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> is greater than zero. 2. <xhtml:strong>The `SeMachineAccountPrivilege` User Right Assignment</xhtml:strong>: Evaluated by the Security Account Manager (SAMR) and NetJoinDomain RPC interfaces when workstations join via standard Windows APIs.</xhtml:p>
        <xhtml:p>Allowing unprivileged users to create machine accounts introduces critical security risks across multiple Active Directory subsystems:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Privilege Escalation via Resource-Based Constrained Delegation (RBCD)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>The SPN Prerequisite</xhtml:em>*: Exploiting Resource-Based Constrained Delegation requires an account configured with a Service Principal Name (SPN). Standard user accounts cannot register an SPN without elevated administrative permissions (the <xhtml:code>servicePrincipalName</xhtml:code> attribute write is restricted). In contrast, computer accounts automatically receive default SPNs (e.g., <xhtml:code>HOST/&lt;computername&gt;</xhtml:code>, <xhtml:code>RestrictedKrbHost/&lt;computername&gt;</xhtml:code>) upon creation, and the creating user is designated as the object's creator/owner (<xhtml:code>mS-DS-CreatorSID</xhtml:code>), retaining full DACL control.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Coercion and Relaying Vector</xhtml:em>*: When an attacker coerces authentication from an unconstrained or privileged server (e.g., via PetitPotam, PrinterBug/SpoolSample, DFSCoerce, or ShadowCoerce) and relays that NTLM authentication to LDAP/LDAPS, or when an attacker has write permissions over a target computer's <xhtml:code>msDS-AllowedToActOnBehalfOfOtherIdentity</xhtml:code> attribute, they configure the victim system to trust the newly created rogue machine account.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Kerberos S4U Abuse</xhtml:em>*: Using the credentials of the rogue computer account, the attacker executes Kerberos S4U2self (Service-for-User-to-Self) and S4U2proxy protocol extensions to obtain a valid Kerberos service ticket impersonating ANY domain user (including a Domain Admin or Enterprise Admin) to services (CIFS, HTTP, LDAP, WSMAN) on the target host, achieving full host or domain takeover.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Active Directory Certificate Services (ADCS) Exploitation</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Template Enrollment</xhtml:em>*: Many enterprise ADCS certificate templates grant enrollment permissions to <xhtml:code>Domain Computers</xhtml:code> (such as default "Machine" or "Computer" templates, or custom enrollment templates).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain Takeover</xhtml:em>*: If vulnerable certificate templates are present in the environment—such as ESC1 (templates allowing the enrollee to specify a Subject Alternative Name / <xhtml:code>ENROLLEE_SUPPLIES_SUBJECT</xhtml:code>), ESC2/ESC3 (enrollment agent misuse), ESC6 (<xhtml:code>EDITF_ATTRIBUTESUBJECTALTNAME2</xhtml:code> enabled on the CA), or ESC13 (certificate templates linked to issuing policies)—an attacker with a rogue computer account can enroll for a machine certificate, supply the SAN of a Domain Controller or privileged administrative account, and immediately escalate to Domain Admin.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Credential Relaying</xhtml:em>*: A rogue machine account also supplies the computer identity required to participate in ESC8 attacks (relaying coerced machine NTLM authentication to ADCS HTTP Web Enrollment or CES endpoints).</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Local Privilege Escalation via Local Kerberos Relaying (KrbRelay / KrbRelayUp)</xhtml:strong>:</xhtml:li>
          <xhtml:li>* On domain-joined Windows endpoints and servers, attack chains such as KrbRelayUp allow local non-administrative users to elevate directly to <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>.</xhtml:li>
          <xhtml:li>* The exploit leverages <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> to dynamically provision a computer account in Active Directory, configures RBCD against the local machine, triggers a local RPC connection to coerce machine Kerberos authentication, and relays the ticket locally to execute arbitrary code as SYSTEM.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Active Directory Integrated DNS (ADIDNS) Poisoning &amp; WPAD Hijacking</xhtml:strong>:</xhtml:li>
          <xhtml:li>* By default, Active Directory-integrated DNS zones allow authenticated machine accounts to register and dynamically update host (<xhtml:code>A</xhtml:code>) and reverse (<xhtml:code>PTR</xhtml:code>) DNS records.</xhtml:li>
          <xhtml:li>* Attackers can leverage rogue computer accounts to poison DNS zones, hijack hostnames of anticipated servers, or register <xhtml:code>wpad</xhtml:code> (Web Proxy Auto-Discovery) records. This allows the attacker to intercept corporate web traffic, harvest NetNTLM credentials, or conduct adversary-in-the-middle (AitM) attacks.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Network Access Control (NAC) &amp; 802.1X Perimeter Bypass</xhtml:strong>:</xhtml:li>
          <xhtml:li>* Many corporate 802.1X wired and wireless network architectures authenticate connecting devices via machine credentials (e.g., PEAP-MSCHAPv2) or machine certificates linked to domain computer accounts.</xhtml:li>
          <xhtml:li>* An attacker connected to an untrusted switch port, guest network, or rogue access point can create a machine account, complete 802.1X machine authentication, and gain unrestricted network placement into internal corporate workstation or server VLANs.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Shadow Credentials (`msDS-KeyCredentialLink`) &amp; Evasive Persistence</xhtml:strong>:</xhtml:li>
          <xhtml:li>* Because the creator possesses owner permissions on the newly created machine account, an attacker can write to the <xhtml:code>msDS-KeyCredentialLink</xhtml:code> attribute to configure public-key credentials (PKINIT). The attacker can then request Kerberos TGTs at will, maintaining persistent directory access without ever modifying the machine's password or triggering password rotation alarms.</xhtml:li>
          <xhtml:li>* Machine accounts automatically join the <xhtml:code>Domain Computers</xhtml:code> global group, granting them persistent ambient access to read Active Directory LDAP partitions, SYSVOL and Netlogon shares, Group Policy Objects, and any internal resources open to domain members.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Historical Precedent: sAMAccountName Spoofing (noPac / CVE-2021-42278 &amp; CVE-2021-42287)</xhtml:strong>:</xhtml:li>
          <xhtml:li>* The noPac exploit demonstrated how unprivileged computer creation is weaponized: attackers created a computer account, stripped the trailing <xhtml:code>$</xhtml:code>, obtained a TGT, renamed the account to match a Domain Controller, and requested a service ticket via S4U2self to impersonate the DC. While specific CVEs are patched, setting <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> to 0 eliminates the fundamental entry point for any future exploit chain that relies on creating arbitrary machine objects.</xhtml:li>
        </xhtml:ol>
        <xhtml:p>Restricting this behavior by setting <xhtml:code>ms-DS-MachineAccountQuota</xhtml:code> to <xhtml:strong>0</xhtml:strong> and removing <xhtml:code>Authenticated Users</xhtml:code> from the <xhtml:code>SeMachineAccountPrivilege</xhtml:code> ("Add workstations to domain") user right ensures that only authorized administrators and dedicated provisioning systems can introduce computer objects into the directory.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Center &amp; GPMC (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Set ms-DS-MachineAccountQuota to 0</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller or administrative host with <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>View</xhtml:strong> in the top menu and ensure <xhtml:strong>Advanced Features</xhtml:strong> is checked.</xhtml:li>
          <xhtml:li>Right-click the root domain object (e.g., <xhtml:code>domain.local</xhtml:code>) and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Attribute Editor</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Scroll down to select the <xhtml:strong>ms-DS-MachineAccountQuota</xhtml:strong> attribute and click <xhtml:strong>Edit</xhtml:strong>.</xhtml:li>
          <xhtml:li>Change the value to <xhtml:strong>0</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Restrict 'Add workstations to domain' GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the <xhtml:strong>Default Domain Controllers Policy</xhtml:strong> or another GPO applying to all Domain Controllers.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
          </xhtml:li>
          <xhtml:li>Locate the policy <xhtml:strong>Add workstations to domain</xhtml:strong>.</xhtml:li>
          <xhtml:li>Double-click the policy, check <xhtml:strong>Define these policy settings</xhtml:strong>, and ensure that only authorized administrative groups (e.g., <xhtml:code>Administrators</xhtml:code>) are added. Remove <xhtml:strong>Authenticated Users</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and remediate these settings.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-MachineAccountQuota.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-MachineAccountQuota.ps1">Download Script: Audit-MachineAccountQuota.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-MachineAccountQuota.ps1
# Description: Audits the domain-wide machine account quota attribute and local Add workstations to domain user right assignment.

Import-Module ActiveDirectory

Write-Host "--- Auditing Machine Account Quota Settings ---" -ForegroundColor Cyan

# 1. Audit domain-wide ms-DS-MachineAccountQuota
try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $Quota = $Domain.MachineAccountQuota

    if ($Quota -ne 0) {
        Write-Host "VULNERABLE: Domain-wide ms-DS-MachineAccountQuota is set to $($Quota) (should be 0)." -ForegroundColor Red
    } else {
        Write-Host "Status: Compliant. Domain-wide ms-DS-MachineAccountQuota is set to 0." -ForegroundColor Green
    }
} catch {
    Write-Host "VULNERABLE: Could not audit ms-DS-MachineAccountQuota. Error: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Audit local User Rights Assignment for SeMachineAccountPrivilege
try {
    $SecCfg = "$($env:temp)\auditpolicy.inf"
    secedit /export /cfg $SecCfg /quiet

    if (Test-Path $SecCfg) {
        $cfgContent = Get-Content -Path $SecCfg
        $privilege = $cfgContent | Where-Object { $_ -like "SeMachineAccountPrivilege*" }

        if ($privilege) {
            $parts = $privilege -split "="
            if ($parts.Count -eq 2) {
                $value = $parts[1].Trim()
                if ($value -eq "*S-1-5-32-544") {
                    Write-Host "Status: Compliant. SeMachineAccountPrivilege is restricted to Administrators." -ForegroundColor Green
                } elseif ($value -eq "") {
                    Write-Host "Status: Compliant. SeMachineAccountPrivilege is empty (no one has the privilege)." -ForegroundColor Green
                } else {
                    Write-Host "VULNERABLE: SeMachineAccountPrivilege is assigned to: $($value) (should be restricted to Administrators or empty)." -ForegroundColor Red
                }
            } else {
                Write-Host "VULNERABLE: Could not parse SeMachineAccountPrivilege line: $($privilege)" -ForegroundColor Red
            }
        } else {
            Write-Host "VULNERABLE: SeMachineAccountPrivilege line not defined in exported local policy (defaults to Authenticated Users)." -ForegroundColor Red
        }
        Remove-Item -Path $SecCfg -Force
    } else {
        Write-Host "VULNERABLE: Could not export local security policy database using secedit." -ForegroundColor Red
    }
} catch {
    Write-Host "VULNERABLE: Could not audit SeMachineAccountPrivilege. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Set-MachineAccountQuota.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-MachineAccountQuota.ps1">Download Script: Set-MachineAccountQuota.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-MachineAccountQuota.ps1
# Description: Sets the domain-wide machine account quota to 0 and restricts the local Add workstations to domain user right to Administrators.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Disable Machine Account Quota..." -ForegroundColor Cyan

# 1. Remediate domain-wide ms-DS-MachineAccountQuota
try {
    $Domain = Get-ADDomain -ErrorAction Stop
    if ($Domain.MachineAccountQuota -ne 0) {
        Set-ADDomain -Identity $Domain.DistinguishedName -Replace @{ "ms-DS-MachineAccountQuota" = 0 } -ErrorAction Stop
        Write-Host "[+] Domain-wide ms-DS-MachineAccountQuota successfully set to 0." -ForegroundColor Green
    } else {
        Write-Host "[-] Domain-wide ms-DS-MachineAccountQuota is already set to 0." -ForegroundColor Yellow
    }
} catch {
    Write-Error "Failed to set ms-DS-MachineAccountQuota. Error: $($_.Exception.Message)"
}

# 2. Remediate local User Rights Assignment (SeMachineAccountPrivilege)
try {
    $SecDb = "$($env:temp)\localpolicy.sdb"
    $SecCfg = "$($env:temp)\localpolicy.inf"
    
    # Export current security policy
    secedit /export /cfg $SecCfg /quiet
    
    if (Test-Path $SecCfg) {
        $cfgContent = Get-Content -Path $SecCfg
        $newCfg = New-Object System.Collections.Generic.List[string]
        $hasPrivilege = $false
        
        foreach ($line in $cfgContent) {
            if ($line -like "SeMachineAccountPrivilege*") {
                $line = "SeMachineAccountPrivilege = *S-1-5-32-544"
                $hasPrivilege = $true
            }
            $newCfg.Add($line) | Out-Null
        }
        
        if (-not $hasPrivilege) {
            # Add to [Privilege Rights] section
            $privIndex = $newCfg.IndexOf("[Privilege Rights]")
            if ($privIndex -ge 0) {
                $newCfg.Insert($privIndex + 1, "SeMachineAccountPrivilege = *S-1-5-32-544")
            } else {
                # Fallback: append section and value
                $newCfg.Add("[Privilege Rights]") | Out-Null
                $newCfg.Add("SeMachineAccountPrivilege = *S-1-5-32-544") | Out-Null
            }
        }
        
        # Save updated configuration
        $newCfg | Set-Content -Path $SecCfg
        
        # Configure local security policy
        secedit /configure /db $SecDb /cfg $SecCfg /areas USER_RIGHTS /quiet
        
        # Cleanup temporary files
        Remove-Item -Path $SecCfg -Force
        Remove-Item -Path $SecDb -Force
        
        Write-Host "[+] Local User Rights Assignment SeMachineAccountPrivilege successfully restricted to Administrators (*S-1-5-32-544)." -ForegroundColor Green
    } else {
        Write-Error "Failed to export local security policy for remediation."
    }
} catch {
    Write-Error "Failed to configure SeMachineAccountPrivilege. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-MachineAccountQuota.ps1
# Description: Sets the domain-wide machine account quota to 0 and restricts the local Add workstations to domain user right to Administrators.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Disable Machine Account Quota..." -ForegroundColor Cyan

# 1. Remediate domain-wide ms-DS-MachineAccountQuota
try {
    $Domain = Get-ADDomain -ErrorAction Stop
    if ($Domain.MachineAccountQuota -ne 0) {
        Set-ADDomain -Identity $Domain.DistinguishedName -Replace @{ "ms-DS-MachineAccountQuota" = 0 } -ErrorAction Stop
        Write-Host "[+] Domain-wide ms-DS-MachineAccountQuota successfully set to 0." -ForegroundColor Green
    } else {
        Write-Host "[-] Domain-wide ms-DS-MachineAccountQuota is already set to 0." -ForegroundColor Yellow
    }
} catch {
    Write-Error "Failed to set ms-DS-MachineAccountQuota. Error: $($_.Exception.Message)"
}

# 2. Remediate local User Rights Assignment (SeMachineAccountPrivilege)
try {
    $SecDb = "$($env:temp)\localpolicy.sdb"
    $SecCfg = "$($env:temp)\localpolicy.inf"
    
    # Export current security policy
    secedit /export /cfg $SecCfg /quiet
    
    if (Test-Path $SecCfg) {
        $cfgContent = Get-Content -Path $SecCfg
        $newCfg = New-Object System.Collections.Generic.List[string]
        $hasPrivilege = $false
        
        foreach ($line in $cfgContent) {
            if ($line -like "SeMachineAccountPrivilege*") {
                $line = "SeMachineAccountPrivilege = *S-1-5-32-544"
                $hasPrivilege = $true
            }
            $newCfg.Add($line) | Out-Null
        }
        
        if (-not $hasPrivilege) {
            # Add to [Privilege Rights] section
            $privIndex = $newCfg.IndexOf("[Privilege Rights]")
            if ($privIndex -ge 0) {
                $newCfg.Insert($privIndex + 1, "SeMachineAccountPrivilege = *S-1-5-32-544")
            } else {
                # Fallback: append section and value
                $newCfg.Add("[Privilege Rights]") | Out-Null
                $newCfg.Add("SeMachineAccountPrivilege = *S-1-5-32-544") | Out-Null
            }
        }
        
        # Save updated configuration
        $newCfg | Set-Content -Path $SecCfg
        
        # Configure local security policy
        secedit /configure /db $SecDb /cfg $SecCfg /areas USER_RIGHTS /quiet
        
        # Cleanup temporary files
        Remove-Item -Path $SecCfg -Force
        Remove-Item -Path $SecDb -Force
        
        Write-Host "[+] Local User Rights Assignment SeMachineAccountPrivilege successfully restricted to Administrators (*S-1-5-32-544)." -ForegroundColor Green
    } else {
        Write-Error "Failed to export local security policy for remediation."
    }
} catch {
    Write-Error "Failed to configure SeMachineAccountPrivilege. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3017" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-018" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-018] Restrict Pre-Windows 2000 Compatible Access Group</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Domain Environment</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/restrict-pre-windows-2000-compatible-access-group.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The "Pre-Windows 2000 Compatible Access" group (SID: <xhtml:code>S-1-5-32-554</xhtml:code>) is a legacy Active Directory security group designed to provide backward compatibility for NT4-era operating systems. By default, this group has broad read permissions to all user and group object attributes within the domain.</xhtml:p>
        <xhtml:p>Historically, groups like "Everyone" (<xhtml:code>S-1-1-0</xhtml:code>), "Anonymous Logon" (<xhtml:code>S-1-5-7</xhtml:code>), or "Authenticated Users" (<xhtml:code>S-1-5-11</xhtml:code>) were added to this group to maintain compatibility. The security risks include:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Information Enumeration</xhtml:strong>: Any authenticated user (or an unauthenticated attacker via anonymous/everyone permissions) can query the Active Directory database to enumerate user lists, group memberships, trust details, and account metadata.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Reconnaissance Surface</xhtml:strong>: Attackers use null-sessions or low-privileged domain accounts to profile the entire AD infrastructure, mapping target groups (like Domain Admins) and identifying service accounts for targeted attacks like Kerberoasting.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Implicit Trust Abuse</xhtml:strong>: Relying on legacy broad-read access bypasses modern Active Directory object-level Access Control List (ACL) restrictions.</xhtml:li>
        </xhtml:ol>
        <xhtml:p>Removing insecure principals from this group and enforcing anonymous access restrictions restricts AD object access to authenticated, authorized accounts only.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Restrict Group Membership</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the <xhtml:strong>Domain Controllers</xhtml:strong> OU (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Restricted Groups</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Restricted Groups</xhtml:strong> and select <xhtml:strong>Add Group...</xhtml:strong>.</xhtml:li>
          <xhtml:li>Type <xhtml:strong>Pre-Windows 2000 Compatible Access</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the group properties dialog, under <xhtml:strong>Members of this group</xhtml:strong>, ensure the list is empty (or contains only authorized service accounts/CA computer accounts). Ensure <xhtml:strong>Everyone</xhtml:strong>, <xhtml:strong>Anonymous Logon</xhtml:strong>, and <xhtml:strong>Authenticated Users</xhtml:strong> are not listed.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Configure Supporting Anonymous Access Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network access: Let Everyone permissions apply to anonymous users</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network access: Do not allow anonymous enumeration of SAM accounts and shares</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Network access: Do not allow anonymous enumeration of SAM accounts</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and remediate these configurations.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-PreWin2000Group.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-PreWin2000Group.ps1">Download Script: Audit-PreWin2000Group.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-PreWin2000Group.ps1
# Description: Audits the Pre-Windows 2000 Compatible Access group membership and local LSA registry configurations.

Import-Module ActiveDirectory

Write-Host "--- Auditing Pre-Windows 2000 Compatible Access Settings ---" -ForegroundColor Cyan

$GroupSid = "S-1-5-32-554"
$CriticalNonCompliantSids = @("S-1-1-0", "S-1-5-7") # Everyone, Anonymous Logon
$RestrictedNonCompliantSids = @("S-1-5-11")          # Authenticated Users (default in modern systems, high legacy impact if removed)
$Vulnerable = $false
$HasWarning = $false

# 1. Audit Group Membership
try {
    $Group = Get-ADGroup -Identity $GroupSid -Properties Members -ErrorAction Stop
    $MembersSids = New-Object System.Collections.Generic.List[string]

    foreach ($MemberDN in $Group.Members) {
        $MemberObj = Get-ADObject -Identity $MemberDN -ErrorAction SilentlyContinue
        if ($null -ne $MemberObj) {
            $MembersSids.Add($MemberObj.SID.Value) | Out-Null
        }
    }

    # Check for Critical SIDs (Everyone, Anonymous Logon)
    foreach ($Sid in $CriticalNonCompliantSids) {
        if ($MembersSids.Contains($Sid)) {
            $Vulnerable = $true
            $Name = ""
            if ($Sid -eq "S-1-1-0") { $Name = "Everyone" }
            elseif ($Sid -eq "S-1-5-7") { $Name = "Anonymous Logon" }

            Write-Host "VULNERABLE: '$($Name)' ($($Sid)) is a member of the Pre-Windows 2000 Compatible Access group." -ForegroundColor Red
        }
    }

    # Check for Authenticated Users (High legacy impact warning)
    foreach ($Sid in $RestrictedNonCompliantSids) {
        if ($MembersSids.Contains($Sid)) {
            $HasWarning = $true
            Write-Host "WARNING: 'Authenticated Users' ($($Sid)) is a member of the Pre-Windows 2000 Compatible Access group. (This is default in modern systems; remove with caution)." -ForegroundColor Yellow
        }
    }

    if (-not $Vulnerable -and -not $HasWarning) {
        Write-Host "Status: Compliant. Pre-Windows 2000 Compatible Access group membership is restricted." -ForegroundColor Green
    } elseif (-not $Vulnerable) {
        Write-Host "Status: Compliant (with warnings). Critical groups are removed, but legacy/default Authenticated Users remains." -ForegroundColor Green
    }
} catch {
    Write-Host "VULNERABLE: Could not query Pre-Windows 2000 Compatible Access group membership. Error: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Audit LSA Registry Security Settings
$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

$Settings = @{
    "EveryoneIncludesAnonymous" = 0
    "RestrictAnonymous"         = 1
    "RestrictAnonymousSAM"      = 1
}

foreach ($Key in $Settings.Keys) {
    try {
        if (Test-Path $LsaPath) {
            $Value = Get-ItemPropertyValue -Path $LsaPath -Name $Key -ErrorAction Stop
            $TargetValue = $Settings[$Key]
            
            if ($Value -ne $TargetValue) {
                Write-Host "VULNERABLE: LSA Registry Key '$($Key)' is set to $($Value) (should be $($TargetValue))." -ForegroundColor Red
            } else {
                Write-Host "Status: Compliant. LSA Registry Key '$($Key)' is set to $($TargetValue)." -ForegroundColor Green
            }
        } else {
            Write-Host "VULNERABLE: LSA registry path does not exist." -ForegroundColor Red
        }
    } catch {
        Write-Host "VULNERABLE: Could not audit LSA key '$($Key)'. Error: $($_.Exception.Message)" -ForegroundColor Red
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Set-PreWin2000Group.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PreWin2000Group.ps1">Download Script: Set-PreWin2000Group.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PreWin2000Group.ps1
# Description: Restricts Pre-Windows 2000 Compatible Access group membership and configures LSA registry security keys.

Import-Module ActiveDirectory

# Configuration Switch: Set to $true if you want to remove 'Authenticated Users' (S-1-5-11).
# WARNING: Removing Authenticated Users can break legacy Samba/SSSD clients, Cisco ISE, and other querying integrations.
$RemoveAuthenticatedUsers = $false

Write-Host "Applying hardening requirement: Restrict Pre-Windows 2000 Compatible Access..." -ForegroundColor Cyan

$GroupSid = "S-1-5-32-554"
$NonCompliantSids = @("S-1-1-0", "S-1-5-7") # Critical SIDs to remove (Everyone, Anonymous Logon)

if ($RemoveAuthenticatedUsers) {
    $NonCompliantSids += "S-1-5-11" # Add Authenticated Users to the removal list
}

# 1. Remediate Group Membership
try {
    $Group = Get-ADGroup -Identity $GroupSid -Properties Members -ErrorAction Stop
    $MembersToRemove = New-Object System.Collections.Generic.List[string]

    foreach ($MemberDN in $Group.Members) {
        $MemberObj = Get-ADObject -Identity $MemberDN -ErrorAction SilentlyContinue
        if ($null -ne $MemberObj) {
            $Sid = $MemberObj.SID.Value
            if ($NonCompliantSids -contains $Sid) {
                $MembersToRemove.Add($MemberDN) | Out-Null
            }
        }
    }

    if ($MembersToRemove.Count -gt 0) {
        foreach ($MemberDN in $MembersToRemove) {
            try {
                Remove-ADGroupMember -Identity $GroupSid -Members $MemberDN -Confirm:$false -ErrorAction Stop
                Write-Host "[+] Successfully removed '$($MemberDN)' from the group." -ForegroundColor Green
            } catch {
                Write-Host "[-] Failed to remove '$($MemberDN)'. Error: $($_.Exception.Message)" -ForegroundColor Red
            }
        }
    } else {
        Write-Host "[-] No non-compliant members found in Pre-Windows 2000 Compatible Access group." -ForegroundColor Yellow
    }
} catch {
    Write-Error "Failed to remediate Pre-Windows 2000 Compatible Access group membership. Error: $($_.Exception.Message)"
}

# 2. Remediate LSA Registry Settings
$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

$Settings = @{
    "EveryoneIncludesAnonymous" = 0
    "RestrictAnonymous"         = 1
    "RestrictAnonymousSAM"      = 1
}

foreach ($Key in $Settings.Keys) {
    try {
        if (-not (Test-Path $LsaPath)) {
            New-Item -Path $LsaPath -Force | Out-Null
        }
        
        $TargetValue = $Settings[$Key]
        Set-ItemProperty -Path $LsaPath -Name $Key -Value $TargetValue -Type DWord -ErrorAction Stop
        Write-Host "[+] Registry Key '$($Key)' successfully set to $($TargetValue)." -ForegroundColor Green
    } catch {
        Write-Error "Failed to apply LSA Registry Key '$($Key)'. Error: $($_.Exception.Message)"
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PreWin2000Group.ps1
# Description: Restricts Pre-Windows 2000 Compatible Access group membership and configures LSA registry security keys.

Import-Module ActiveDirectory

# Configuration Switch: Set to $true if you want to remove 'Authenticated Users' (S-1-5-11).
# WARNING: Removing Authenticated Users can break legacy Samba/SSSD clients, Cisco ISE, and other querying integrations.
$RemoveAuthenticatedUsers = $false

Write-Host "Applying hardening requirement: Restrict Pre-Windows 2000 Compatible Access..." -ForegroundColor Cyan

$GroupSid = "S-1-5-32-554"
$NonCompliantSids = @("S-1-1-0", "S-1-5-7") # Critical SIDs to remove (Everyone, Anonymous Logon)

if ($RemoveAuthenticatedUsers) {
    $NonCompliantSids += "S-1-5-11" # Add Authenticated Users to the removal list
}

# 1. Remediate Group Membership
try {
    $Group = Get-ADGroup -Identity $GroupSid -Properties Members -ErrorAction Stop
    $MembersToRemove = New-Object System.Collections.Generic.List[string]

    foreach ($MemberDN in $Group.Members) {
        $MemberObj = Get-ADObject -Identity $MemberDN -ErrorAction SilentlyContinue
        if ($null -ne $MemberObj) {
            $Sid = $MemberObj.SID.Value
            if ($NonCompliantSids -contains $Sid) {
                $MembersToRemove.Add($MemberDN) | Out-Null
            }
        }
    }

    if ($MembersToRemove.Count -gt 0) {
        foreach ($MemberDN in $MembersToRemove) {
            try {
                Remove-ADGroupMember -Identity $GroupSid -Members $MemberDN -Confirm:$false -ErrorAction Stop
                Write-Host "[+] Successfully removed '$($MemberDN)' from the group." -ForegroundColor Green
            } catch {
                Write-Host "[-] Failed to remove '$($MemberDN)'. Error: $($_.Exception.Message)" -ForegroundColor Red
            }
        }
    } else {
        Write-Host "[-] No non-compliant members found in Pre-Windows 2000 Compatible Access group." -ForegroundColor Yellow
    }
} catch {
    Write-Error "Failed to remediate Pre-Windows 2000 Compatible Access group membership. Error: $($_.Exception.Message)"
}

# 2. Remediate LSA Registry Settings
$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

$Settings = @{
    "EveryoneIncludesAnonymous" = 0
    "RestrictAnonymous"         = 1
    "RestrictAnonymousSAM"      = 1
}

foreach ($Key in $Settings.Keys) {
    try {
        if (-not (Test-Path $LsaPath)) {
            New-Item -Path $LsaPath -Force | Out-Null
        }
        
        $TargetValue = $Settings[$Key]
        Set-ItemProperty -Path $LsaPath -Name $Key -Value $TargetValue -Type DWord -ErrorAction Stop
        Write-Host "[+] Registry Key '$($Key)' successfully set to $($TargetValue)." -ForegroundColor Green
    } catch {
        Write-Error "Failed to apply LSA Registry Key '$($Key)'. Error: $($_.Exception.Message)"
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3018" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-019" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-019] Enforce Smart Card Authentication for Privileged Users</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Services (AD DS) user accounts, Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above)</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/enforce-smartcard-privileged-users.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Enforcing smart card authentication on privileged accounts significantly mitigates the risk of credential theft, lateral movement, and offline password cracking:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Hash and Password Extraction Prevention</xhtml:strong>: By checking "Smart card is required for interactive logon" on an Active Directory user account, AD automatically rotates the account's password to a cryptographically strong, random 120-character string that is unknown to the user. This effectively invalidates the traditional NTHash and LMHash authentication methods, preventing attackers from performing password-spraying or brute-force attacks against administrative logins.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Replay and Relay Mitigation</xhtml:strong>: Password-based authentication relies on credentials that can be captured, logged, or relay-attacked. Using smart cards (or physical tokens like YubiKeys) shifts authentication to Kerberos PKINIT (Public Key Cryptography for Initial Authentication in Kerberos). This protocol relies on private keys stored in the card's secure hardware element, ensuring credentials cannot be copied or replayed.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Physical Presence Factor</xhtml:strong>: Combining a hardware token (something you have) and a PIN (something you know) establishes true multi-factor authentication (MFA) for administrative activities, preventing unauthorized access by remote network attackers who have compromised a password.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Tools (Preferred)</xhtml:h3>
        <xhtml:p>To configure smart card requirement for individual privileged users or OUs: 1. Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>) on a domain controller or administrative host. 2. Navigate to the Organizational Unit (OU) containing your administrative users. 3. Right-click the target administrator account and select <xhtml:strong>Properties</xhtml:strong>. 4. Click on the <xhtml:strong>Account</xhtml:strong> tab. 5. In the <xhtml:strong>Account options</xhtml:strong> window, scroll down and check the box: <xhtml:strong>Smart card is required for interactive logon</xhtml:strong>. 6. Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:p>
        <xhtml:p>Alternatively, you can select multiple users at once, right-click, select <xhtml:strong>Properties</xhtml:strong>, click the <xhtml:strong>Account</xhtml:strong> tab, select the check box next to <xhtml:strong>Smart card is required for interactive logon</xhtml:strong> under <xhtml:strong>Account options</xhtml:strong>, and click <xhtml:strong>OK</xhtml:strong> to apply the policy in batch.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Script (Remediation / Automation)</xhtml:h3>
        <xhtml:p>Use these scripts locally on a Domain Controller or a management machine with Active Directory administrative tools installed to enforce or audit the smart card requirement.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PrivilegedSmartCard.ps1">Download Script: Configure-PrivilegedSmartCard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PrivilegedSmartCard.ps1
# Description: Enforces the 'Smart card is required for interactive logon' flag on a specified user group.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying smart card logon requirement to administrative accounts..." -ForegroundColor Cyan

if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "ActiveDirectory PowerShell module is not available. Please run this script on a system with AD DS RSAT tools."
    exit 1
}

Import-Module ActiveDirectory

$GroupName = "Tier0_Administrators"
$Group = Get-ADGroup -Filter "Name -eq '$GroupName'"
if (-not $Group) {
    Write-Host "Group $GroupName not found. Defaulting to Domain Admins..." -ForegroundColor Yellow
    $GroupName = "Domain Admins"
}

$Members = Get-ADGroupMember -Identity $GroupName -Recursive | Where-Object { $_.objectClass -eq "user" }

if (-not $Members) {
    Write-Host "No users found in group $GroupName." -ForegroundColor Yellow
    exit 0
}

foreach ($Member in $Members) {
    $User = Get-ADUser -Identity $Member.distinguishedName -Properties SmartcardRequired
    if (-not $User.SmartcardRequired) {
        Write-Host "Enforcing smart card requirement for user: $($User.SamAccountName)" -ForegroundColor Cyan
        Set-ADUser -Identity $User.distinguishedName -SmartcardRequired $true
    } else {
        Write-Host "User $($User.SamAccountName) already requires smart card." -ForegroundColor Green
    }
}

Write-Host "Smart card requirement configuration complete." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the smart card requirement on privileged users:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PrivilegedSmartCard.ps1">Download Script: Test-PrivilegedSmartCard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PrivilegedSmartCard.ps1
# Description: Audits if all members of the specified administrative group require smart card for logon.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing Privileged User Smart Card Requirements ---" -ForegroundColor Cyan

if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Warning "ActiveDirectory PowerShell module is not available. Please install RSAT AD DS tools."
    exit 0
}

Import-Module ActiveDirectory

$GroupName = "Tier0_Administrators"
$Group = Get-ADGroup -Filter "Name -eq '$GroupName'"
if (-not $Group) {
    Write-Host "Group $GroupName not found. Defaulting audit to Domain Admins..." -ForegroundColor Yellow
    $GroupName = "Domain Admins"
}

$Vulnerable = $false
$Members = Get-ADGroupMember -Identity $GroupName -Recursive | Where-Object { $_.objectClass -eq "user" }

if (-not $Members) {
    Write-Host "No users found in group $GroupName to audit." -ForegroundColor Yellow
} else {
    foreach ($Member in $Members) {
        $User = Get-ADUser -Identity $Member.distinguishedName -Properties SmartcardRequired
        if (-not $User.SmartcardRequired) {
            Write-Host "    - User: $($User.SamAccountName) | Actual: Password Allowed (Expected: Smart Card Required)" -ForegroundColor Red
            $Vulnerable = $true
        } else {
            Write-Host "    - User: $($User.SamAccountName) | Actual: Smart Card Required (Expected: Smart Card Required)" -ForegroundColor Green
        }
    }
}

if ($Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PrivilegedSmartCard.ps1
# Description: Enforces the 'Smart card is required for interactive logon' flag on a specified user group.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying smart card logon requirement to administrative accounts..." -ForegroundColor Cyan

if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "ActiveDirectory PowerShell module is not available. Please run this script on a system with AD DS RSAT tools."
    exit 1
}

Import-Module ActiveDirectory

$GroupName = "Tier0_Administrators"
$Group = Get-ADGroup -Filter "Name -eq '$GroupName'"
if (-not $Group) {
    Write-Host "Group $GroupName not found. Defaulting to Domain Admins..." -ForegroundColor Yellow
    $GroupName = "Domain Admins"
}

$Members = Get-ADGroupMember -Identity $GroupName -Recursive | Where-Object { $_.objectClass -eq "user" }

if (-not $Members) {
    Write-Host "No users found in group $GroupName." -ForegroundColor Yellow
    exit 0
}

foreach ($Member in $Members) {
    $User = Get-ADUser -Identity $Member.distinguishedName -Properties SmartcardRequired
    if (-not $User.SmartcardRequired) {
        Write-Host "Enforcing smart card requirement for user: $($User.SamAccountName)" -ForegroundColor Cyan
        Set-ADUser -Identity $User.distinguishedName -SmartcardRequired $true
    } else {
        Write-Host "User $($User.SamAccountName) already requires smart card." -ForegroundColor Green
    }
}

Write-Host "Smart card requirement configuration complete." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3019" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-ID-020" severity="high" weight="10.0" selected="false">
      <title>[REQ-ID-020] Clean Up Legacy Group Policy Preferences and SYSVOL Passwords</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>03-identities-services/cleanup-gpp-sysvol-passwords.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Historically, administrators utilized Group Policy Preferences (GPP) to automate account creation, service configurations, drive mappings, and local administrator password rotations. When credentials were saved within a GPP, the password was stored as an encrypted string under the <xhtml:code>cpassword</xhtml:code> attribute in XML configuration files (e.g., <xhtml:code>Groups.xml</xhtml:code>, <xhtml:code>Services.xml</xhtml:code>, <xhtml:code>ScheduledTasks.xml</xhtml:code>) inside the domain-wide <xhtml:code>SYSVOL</xhtml:code> share.</xhtml:p>
        <xhtml:p>Although Microsoft encrypted the password with AES-256, the static AES decryption key was published on MSDN. Because any authenticated user (or trust) has read access to the <xhtml:code>SYSVOL</xhtml:code> share, any domain user can read the preference XML files, extract the <xhtml:code>cpassword</xhtml:code> value, and decrypt it to obtain cleartext credentials.</xhtml:p>
        <xhtml:p>Microsoft patched this vulnerability in May 2014 via <xhtml:strong>MS14-025 (KB2962486)</xhtml:strong>, which blocks the Group Policy Management Console (GPMC) from creating or updating policies that contain password fields. However, <xhtml:strong>the patch does not delete existing GPP XML files with passwords from SYSVOL</xhtml:strong>. Consequently, legacy preferences with encrypted credentials remain in the <xhtml:code>SYSVOL</xhtml:code> directory and continue to be a primary target for adversary credential harvesting.</xhtml:p>
        <xhtml:p>Additionally, administrators historically deployed custom login or management scripts (e.g., <xhtml:code>.vbs</xhtml:code>, <xhtml:code>.bat</xhtml:code>, <xhtml:code>.cmd</xhtml:code>, <xhtml:code>.ps1</xhtml:code>) in <xhtml:code>SYSVOL</xhtml:code> with cleartext passwords hardcoded. These must also be identified and purged.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Group Policy Management (GUI)</xhtml:h3>
        <xhtml:p>To manually locate and clean up credential fields: 1. Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management server. 2. Review all active GPOs that configure Preferences (specifically under <xhtml:strong>Computer Configuration</xhtml:strong> or <xhtml:strong>User Configuration</xhtml:strong> -&gt; <xhtml:strong>Preferences</xhtml:strong> -&gt; <xhtml:strong>Control Panel Settings</xhtml:strong> -&gt; <xhtml:strong>Local Users and Groups</xhtml:strong>, <xhtml:strong>Scheduled Tasks</xhtml:strong>, or <xhtml:strong>Services</xhtml:strong>). 3. If an active policy contains an account configuration with a password, recreate the policy option without specifying credentials (use LAPS or gMSA as alternatives). 4. For any GPOs no longer in use, delete them using GPMC to clean up their folders from the <xhtml:code>SYSVOL</xhtml:code> directory.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Remediation (Non-GPO / Script-based)</xhtml:h3>
        <xhtml:p>Use these scripts to scan and automatically remediate GPP configuration files in the <xhtml:code>SYSVOL</xhtml:code> share.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Remove-GPPSYSVOLPasswords.ps1">Download Script: Remove-GPPSYSVOLPasswords.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Remove-GPPSYSVOLPasswords.ps1
# Description: Removes cpassword attributes from Group Policy Preference XML files in SYSVOL and backs up original files.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Remediation: Cleaning Up GPP cpassword Credentials in SYSVOL ---" -ForegroundColor Cyan

# Retrieve local SYSVOL path from registry
$SysvolReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "Sysvol" -ErrorAction SilentlyContinue
if (-not $SysvolReg) {
    Write-Host "[*] SYSVOL registry path not found. Checking standard share path..." -ForegroundColor Yellow
    $SysvolPath = "C:\Windows\SYSVOL\sysvol"
} else {
    $SysvolPath = $SysvolReg.Sysvol
}

if (-not (Test-Path -Path $SysvolPath)) {
    Write-Host "[-] SYSVOL folder not found at path: $SysvolPath. Nothing to remediate." -ForegroundColor Red
    exit 0
}

# 1. Scan and remediate GPP XML files
$GppXmls = Get-ChildItem -Path $SysvolPath -Filter *.xml -Recurse -File -ErrorAction SilentlyContinue

foreach ($file in $GppXmls) {
    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content.Contains("cpassword")) {
        Write-Host "[*] Found GPP file with cpassword: $($file.FullName)" -ForegroundColor Yellow
        
        # Create Backup
        $Timestamp = Get-Date -Format "yyyyMMddHHmmss"
        $BackupPath = "$($file.FullName).bak_$Timestamp"
        Copy-Item -Path $file.FullName -Destination $BackupPath -Force -ErrorAction SilentlyContinue
        Write-Host "    [+] Created backup at: $BackupPath" -ForegroundColor Gray

        # Load XML
        [xml]$xml = New-Object System.Xml.XmlDocument
        try {
            $xml.Load($file.FullName)
            
            # Find all elements with cpassword attribute using XPath
            $Nodes = $xml.SelectNodes("//*[@cpassword]")
            if ($Nodes.Count -gt 0) {
                foreach ($Node in $Nodes) {
                    Write-Host "    [+] Stripping cpassword attribute from XML node: $($Node.Name)" -ForegroundColor White
                    $Node.RemoveAttribute("cpassword")
                    # If username exists, log it to help administrator identify what was affected
                    if ($Node.Attributes["username"]) {
                        Write-Host "    [!] Note: Node was configured for username '$($Node.Attributes["username"].Value)'" -ForegroundColor Yellow
                    }
                }
                $xml.Save($file.FullName)
                Write-Host "    [+] Successfully stripped cpassword from: $($file.FullName)" -ForegroundColor Green
            }
        }
        catch {
            Write-Host "    [-] Failed to parse or save XML: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
}

# 2. Alert for scripts (Do not auto-remediate script files to prevent code syntax breakage)
$ScriptFiles = Get-ChildItem -Path $SysvolPath -Include *.vbs, *.ps1, *.bat, *.cmd -Recurse -File -ErrorAction SilentlyContinue
$CredentialPattern = '(?i)\b(password|pwd|adminpwd|syspwd|adminpassword|localadminpwd)\s*=\s*["''][^"'']+\b'

foreach ($file in $ScriptFiles) {
    # Skip our own audit and implementation scripts
    if ($file.Name -like "*Get-GPPSYSVOLPasswords*" -or $file.Name -like "*Remove-GPPSYSVOLPasswords*" -or $file.Name -like "*SYSVOLHoneypot*") {
        continue
    }

    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content -match $CredentialPattern) {
        Write-Host "[WARNING] Script contains hardcoded credential pattern: $($file.FullName)" -ForegroundColor Red
        Write-Host "          Manual intervention is required. Review and delete/rotate credentials in this script." -ForegroundColor Yellow
    }
}

Write-Host "[+] SYSVOL password remediation processing completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that no cpassword files or cleartext script credentials exist in SYSVOL:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-GPPSYSVOLPasswords.ps1">Download Script: Get-GPPSYSVOLPasswords.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-GPPSYSVOLPasswords.ps1
# Description: Audits the SYSVOL directory for legacy Group Policy Preference files containing cpassword values and scripts containing cleartext credentials.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing SYSVOL for Group Policy Preference and Script Passwords ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# Retrieve local SYSVOL path from registry
$SysvolReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "Sysvol" -ErrorAction SilentlyContinue
if (-not $SysvolReg) {
    Write-Host "[*] SYSVOL registry path not found. Checking standard share path..." -ForegroundColor Yellow
    $SysvolPath = "C:\Windows\SYSVOL\sysvol"
} else {
    $SysvolPath = $SysvolReg.Sysvol
}

if (-not (Test-Path -Path $SysvolPath)) {
    Write-Host "[-] SYSVOL folder not found at path: $SysvolPath" -ForegroundColor Red
    exit 0 # Not a Domain Controller or SYSVOL not configured, nothing to audit
}

Write-Host "[*] Scanning SYSVOL directory: $SysvolPath" -ForegroundColor White

# 1. Scan for XML files containing 'cpassword'
$GppXmls = Get-ChildItem -Path $SysvolPath -Filter *.xml -Recurse -File -ErrorAction SilentlyContinue
foreach ($file in $GppXmls) {
    # Read the file content safely
    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content.Contains("cpassword")) {
        Write-Host "[!] VULNERABLE: Group Policy Preference file contains cpassword attribute: $($file.FullName)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# 2. Scan for script files containing cleartext credentials
# Scripts: .vbs, .ps1, .bat, .cmd
$ScriptFiles = Get-ChildItem -Path $SysvolPath -Include *.vbs, *.ps1, *.bat, *.cmd -Recurse -File -ErrorAction SilentlyContinue

# Regex pattern for credentials (e.g. password=, pwd=, adminpwd=)
$CredentialPattern = '(?i)\b(password|pwd|adminpwd|syspwd|adminpassword|localadminpwd)\s*=\s*["''][^"'']+\b'

foreach ($file in $ScriptFiles) {
    # Check if the file is our own audit or implementation scripts (skip those)
    if ($file.Name -like "*Get-GPPSYSVOLPasswords*" -or $file.Name -like "*Remove-GPPSYSVOLPasswords*" -or $file.Name -like "*SYSVOLHoneypot*") {
        continue
    }
    
    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content -match $CredentialPattern) {
        Write-Host "[!] VULNERABLE: Script file contains potential cleartext password: $($file.FullName)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "[+] No Group Policy Preference passwords or cleartext scripts found in SYSVOL." -ForegroundColor Green
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Remove-GPPSYSVOLPasswords.ps1
# Description: Removes cpassword attributes from Group Policy Preference XML files in SYSVOL and backs up original files.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Remediation: Cleaning Up GPP cpassword Credentials in SYSVOL ---" -ForegroundColor Cyan

# Retrieve local SYSVOL path from registry
$SysvolReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "Sysvol" -ErrorAction SilentlyContinue
if (-not $SysvolReg) {
    Write-Host "[*] SYSVOL registry path not found. Checking standard share path..." -ForegroundColor Yellow
    $SysvolPath = "C:\Windows\SYSVOL\sysvol"
} else {
    $SysvolPath = $SysvolReg.Sysvol
}

if (-not (Test-Path -Path $SysvolPath)) {
    Write-Host "[-] SYSVOL folder not found at path: $SysvolPath. Nothing to remediate." -ForegroundColor Red
    exit 0
}

# 1. Scan and remediate GPP XML files
$GppXmls = Get-ChildItem -Path $SysvolPath -Filter *.xml -Recurse -File -ErrorAction SilentlyContinue

foreach ($file in $GppXmls) {
    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content.Contains("cpassword")) {
        Write-Host "[*] Found GPP file with cpassword: $($file.FullName)" -ForegroundColor Yellow
        
        # Create Backup
        $Timestamp = Get-Date -Format "yyyyMMddHHmmss"
        $BackupPath = "$($file.FullName).bak_$Timestamp"
        Copy-Item -Path $file.FullName -Destination $BackupPath -Force -ErrorAction SilentlyContinue
        Write-Host "    [+] Created backup at: $BackupPath" -ForegroundColor Gray

        # Load XML
        [xml]$xml = New-Object System.Xml.XmlDocument
        try {
            $xml.Load($file.FullName)
            
            # Find all elements with cpassword attribute using XPath
            $Nodes = $xml.SelectNodes("//*[@cpassword]")
            if ($Nodes.Count -gt 0) {
                foreach ($Node in $Nodes) {
                    Write-Host "    [+] Stripping cpassword attribute from XML node: $($Node.Name)" -ForegroundColor White
                    $Node.RemoveAttribute("cpassword")
                    # If username exists, log it to help administrator identify what was affected
                    if ($Node.Attributes["username"]) {
                        Write-Host "    [!] Note: Node was configured for username '$($Node.Attributes["username"].Value)'" -ForegroundColor Yellow
                    }
                }
                $xml.Save($file.FullName)
                Write-Host "    [+] Successfully stripped cpassword from: $($file.FullName)" -ForegroundColor Green
            }
        }
        catch {
            Write-Host "    [-] Failed to parse or save XML: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
}

# 2. Alert for scripts (Do not auto-remediate script files to prevent code syntax breakage)
$ScriptFiles = Get-ChildItem -Path $SysvolPath -Include *.vbs, *.ps1, *.bat, *.cmd -Recurse -File -ErrorAction SilentlyContinue
$CredentialPattern = '(?i)\b(password|pwd|adminpwd|syspwd|adminpassword|localadminpwd)\s*=\s*["''][^"'']+\b'

foreach ($file in $ScriptFiles) {
    # Skip our own audit and implementation scripts
    if ($file.Name -like "*Get-GPPSYSVOLPasswords*" -or $file.Name -like "*Remove-GPPSYSVOLPasswords*" -or $file.Name -like "*SYSVOLHoneypot*") {
        continue
    }

    $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue
    if ($content -and $content -match $CredentialPattern) {
        Write-Host "[WARNING] Script contains hardcoded credential pattern: $($file.FullName)" -ForegroundColor Red
        Write-Host "          Manual intervention is required. Review and delete/rotate credentials in this script." -ForegroundColor Yellow
    }
}

Write-Host "[+] SYSVOL password remediation processing completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:3020" />
      </check>
    </Rule>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_4__Network_Configuration___Firewalling">
    <title>Module 4: Network Configuration &amp; Firewalling</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-001] Configure Active Directory Port Matrix</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-ad-port-matrix.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory services require several ports to function, including DNS, Kerberos, LDAP, SMB, and RPC. If firewalls are not configured to restrict traffic to only these essential ports, adversaries can perform internal network scanning, identify open services, exploit vulnerabilities in unhardened services, or pivot across systems.</xhtml:p>
        <xhtml:p>Restricting network communications to the minimum required AD Port Matrix ensures: 1. <xhtml:strong>Attack Surface Reduction</xhtml:strong>: Unused services are blocked from receiving network connections. 2. <xhtml:strong>Reconnaissance Mitigation</xhtml:strong>: Internal port scanning returns blocked states, slowing down discovery. 3. <xhtml:strong>Lateral Movement Containment</xhtml:strong>: Compromised endpoints cannot arbitrary query services on domain controllers or other member systems.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Enforce Default Inbound Block</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the target systems (e.g., <xhtml:code>GPO_Hardening_Firewall_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Windows Defender Firewall with Advanced Security</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>For the <xhtml:strong>Domain Profile</xhtml:strong>, <xhtml:strong>Private Profile</xhtml:strong>, and <xhtml:strong>Public Profile</xhtml:strong> tabs, set:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>State</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Create Inbound Allow Rules for the AD Port Matrix (Domain Controllers GPO)</xhtml:h4>
        <xhtml:p>For GPOs targeting Domain Controllers, configure the following inbound rules under <xhtml:strong>Inbound Rules</xhtml:strong>:</xhtml:p>
        <xhtml:p>| Protocol | Port | Source Subnet | Description | | :--- | :--- | :--- | :--- | | TCP / UDP | 53 | Any / Client Subnets | DNS Resolution | | UDP | 123 | Any / Client Subnets | NTP Time Sync | | TCP / UDP | 88 | Any / Client Subnets | Kerberos Authentication | | TCP / UDP | 464 | Any / Client Subnets | Kerberos Password Change | | TCP / UDP | 389 | Any / Client Subnets | LDAP Directory Queries | | TCP | 636 | Any / Client Subnets | LDAPS (Secure LDAP) | | TCP | 3268 | Any / Client Subnets | Global Catalog Query | | TCP | 3269 | Any / Client Subnets | Global Catalog SSL | | TCP | 135 | Any / Client Subnets | RPC Endpoint Mapper | | TCP | 445 | Any / Client Subnets | SMB (SYSVOL / GPO) | | TCP | 38901 | Any / Client Subnets | NTDS Static RPC Port | | TCP | 38902 | Any / Client Subnets | Netlogon Static RPC Port | | TCP | 5722 | Domain Controller Subnets | DFSR Static RPC Port | | TCP | 3389 | PAW / Jump Host Subnets | RDP (Management) | | TCP | 5985 / 5986 | PAW / Jump Host Subnets | WinRM (Management) |</xhtml:p>
        <xhtml:p>&gt; [!WARNING] &gt; **Static RPC Ports Requirement**: &gt; The NTDS (TCP 38901), Netlogon (TCP 38902), and DFSR (TCP 5722) ports listed above require static port configurations to be active on the target Domain Controllers. If these ports are not explicitly configured to be static on the operating system, remote authentication and replication will fail. See [REQ-NET-002: Restrict RPC Dynamic Ports](restrict-rpc-dynamic-ports.md) for GPO and registry configurations to bind these services to their static endpoints.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and configure the firewall profiles and inbound port rules.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADPortMatrixRules.ps1">Download Script: Set-ADPortMatrixRules.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADPortMatrixRules.ps1
# Configures local Windows Defender Firewall profiles and applies basic AD port matrix baseline rules.

param(
    [string[]]$ManagementAddresses
)

# If not passed, prompt user dynamically
if ($null -eq $ManagementAddresses) {
    if ([Environment]::UserInteractive) {
        $inputVal = Read-Host "Enter remote IP addresses/subnets for remote management (comma-separated, e.g. 10.0.0.0/24,192.168.1.50) [leave empty for LocalSubnet]"
        if ([string]::IsNullOrWhiteSpace($inputVal)) {
            $ManagementAddresses = @("LocalSubnet")
        } else {
            $ManagementAddresses = $inputVal.Split(",") | ForEach-Object { $_.Trim() }
        }
    } else {
        $ManagementAddresses = @("LocalSubnet")
    }
}

Write-Host "Applying network firewall baseline policies..." -ForegroundColor Cyan

# 1. Enable firewall and set default block inbound
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True -DefaultInboundAction Block -DefaultOutboundAction Allow
Write-Host "Firewall profiles enabled with Default Inbound Block." -ForegroundColor Green

# 2. Configure AD Port Matrix inbound rules (for local system role validation)
$Rules = @(
    @{ Name = "AD-DNS-TCP"; Port = 53; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-DNS-UDP"; Port = 53; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-Kerberos-TCP"; Port = 88; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kerberos-UDP"; Port = 88; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-NTP-UDP"; Port = 123; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-RPC-Mapper-TCP"; Port = 135; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-LDAP-TCP"; Port = 389; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-LDAP-UDP"; Port = 389; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-SMB-TCP"; Port = 445; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kpwd-TCP"; Port = 464; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kpwd-UDP"; Port = 464; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-LDAPS-TCP"; Port = 636; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-GC-TCP"; Port = 3268; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-GC-SSL-TCP"; Port = 3269; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-NTDS-Static-TCP"; Port = 38901; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Netlogon-Static-TCP"; Port = 38902; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-DFSR-Static-TCP"; Port = 5722; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-RDP-TCP"; Port = 3389; Proto = "TCP"; Remote = $ManagementAddresses },
    @{ Name = "AD-WinRM-HTTP-TCP"; Port = 5985; Proto = "TCP"; Remote = $ManagementAddresses },
    @{ Name = "AD-WinRM-HTTPS-TCP"; Port = 5986; Proto = "TCP"; Remote = $ManagementAddresses }
)

foreach ($Rule in $Rules) {
    $Name = $Rule.Name
    $Port = $Rule.Port
    $Proto = $Rule.Proto
    $Remote = $Rule.Remote
    
    $Existing = Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -Name $Name -DisplayName $Name `
            -Direction Inbound `
            -Action Allow `
            -Protocol $Proto `
            -LocalPort $Port `
            -RemoteAddress $Remote `
            -Profile Domain, Private `
            -Enabled True | Out-Null
        Write-Host "Inbound rule created: $($Name) on port $($Port) ($($Proto)) from remote address: $($Remote -join ', ')" -ForegroundColor Green
    } else {
        Set-NetFirewallRule -Name $Name -Enabled True -Action Allow -RemoteAddress $Remote | Out-Null
        Write-Host "Inbound rule verified: $($Name) restricted to remote address: $($Remote -join ', ')" -ForegroundColor Gray
    }
}

Write-Host "Firewall port matrix configuration completed successfully." -ForegroundColor Cyan
</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-ADPortMatrixRules.ps1">Download Script: Test-ADPortMatrixRules.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-ADPortMatrixRules.ps1
# Audits local firewall status and checks if default inbound traffic is blocked.

Write-Host "Auditing local network firewall status..." -ForegroundColor Cyan

# 1. Check Windows Defender Firewall State
$Profiles = Get-NetFirewallProfile
$AllProfilesSecure = $true

foreach ($FwProfile in $Profiles) {
    $Enabled = $FwProfile.Enabled
    $InAction = $FwProfile.DefaultInboundAction
    
    if ($Enabled -eq $true -and $InAction -eq "Block") {
        Write-Host "Profile: $($FwProfile.Name) | Enabled: True | InboundAction: Block" -ForegroundColor Green
    } else {
        Write-Host "Profile: $($FwProfile.Name) | Enabled: $($Enabled) | InboundAction: $($InAction) (INSECURE)" -ForegroundColor Red
        $AllProfilesSecure = $false
    }
}

if ($AllProfilesSecure) {
    Write-Host "Audit Result: Firewall state configuration is compliant." -ForegroundColor Green
} else {
    Write-Warning "Audit Result: Firewall profiles are not fully secured!"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADPortMatrixRules.ps1
# Configures local Windows Defender Firewall profiles and applies basic AD port matrix baseline rules.

param(
    [string[]]$ManagementAddresses
)

# If not passed, prompt user dynamically
if ($null -eq $ManagementAddresses) {
    if ([Environment]::UserInteractive) {
        $inputVal = Read-Host "Enter remote IP addresses/subnets for remote management (comma-separated, e.g. 10.0.0.0/24,192.168.1.50) [leave empty for LocalSubnet]"
        if ([string]::IsNullOrWhiteSpace($inputVal)) {
            $ManagementAddresses = @("LocalSubnet")
        } else {
            $ManagementAddresses = $inputVal.Split(",") | ForEach-Object { $_.Trim() }
        }
    } else {
        $ManagementAddresses = @("LocalSubnet")
    }
}

Write-Host "Applying network firewall baseline policies..." -ForegroundColor Cyan

# 1. Enable firewall and set default block inbound
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True -DefaultInboundAction Block -DefaultOutboundAction Allow
Write-Host "Firewall profiles enabled with Default Inbound Block." -ForegroundColor Green

# 2. Configure AD Port Matrix inbound rules (for local system role validation)
$Rules = @(
    @{ Name = "AD-DNS-TCP"; Port = 53; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-DNS-UDP"; Port = 53; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-Kerberos-TCP"; Port = 88; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kerberos-UDP"; Port = 88; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-NTP-UDP"; Port = 123; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-RPC-Mapper-TCP"; Port = 135; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-LDAP-TCP"; Port = 389; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-LDAP-UDP"; Port = 389; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-SMB-TCP"; Port = 445; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kpwd-TCP"; Port = 464; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Kpwd-UDP"; Port = 464; Proto = "UDP"; Remote = "Any" },
    @{ Name = "AD-LDAPS-TCP"; Port = 636; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-GC-TCP"; Port = 3268; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-GC-SSL-TCP"; Port = 3269; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-NTDS-Static-TCP"; Port = 38901; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-Netlogon-Static-TCP"; Port = 38902; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-DFSR-Static-TCP"; Port = 5722; Proto = "TCP"; Remote = "Any" },
    @{ Name = "AD-RDP-TCP"; Port = 3389; Proto = "TCP"; Remote = $ManagementAddresses },
    @{ Name = "AD-WinRM-HTTP-TCP"; Port = 5985; Proto = "TCP"; Remote = $ManagementAddresses },
    @{ Name = "AD-WinRM-HTTPS-TCP"; Port = 5986; Proto = "TCP"; Remote = $ManagementAddresses }
)

foreach ($Rule in $Rules) {
    $Name = $Rule.Name
    $Port = $Rule.Port
    $Proto = $Rule.Proto
    $Remote = $Rule.Remote
    
    $Existing = Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -Name $Name -DisplayName $Name `
            -Direction Inbound `
            -Action Allow `
            -Protocol $Proto `
            -LocalPort $Port `
            -RemoteAddress $Remote `
            -Profile Domain, Private `
            -Enabled True | Out-Null
        Write-Host "Inbound rule created: $($Name) on port $($Port) ($($Proto)) from remote address: $($Remote -join ', ')" -ForegroundColor Green
    } else {
        Set-NetFirewallRule -Name $Name -Enabled True -Action Allow -RemoteAddress $Remote | Out-Null
        Write-Host "Inbound rule verified: $($Name) restricted to remote address: $($Remote -join ', ')" -ForegroundColor Gray
    }
}

Write-Host "Firewall port matrix configuration completed successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-002] Restrict RPC Dynamic Ports</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/restrict-rpc-dynamic-ports.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>By default, the RPC runtime utilizes a massive dynamic range of high-order ports (TCP 49152-65535) for communication, including Active Directory replication, netlogon authentication, and DFS replication.</xhtml:p>
        <xhtml:p>Opening this entire dynamic port range in network-based firewalls for all systems exposes an unmonitored attack surface. To mitigate this risk, key domain controller services (NTDS, Netlogon, and DFSR) must be bound to dedicated static ports (TCP 38901, 38902, and 5722 respectively). This allows network administrators to configure precise firewall rules permitting only these ports.</xhtml:p>
        <xhtml:p>Crucially, <xhtml:strong>the system-wide dynamic RPC range must NOT be narrowed</xhtml:strong> (such as restricting it globally to 50000-50100). Restricting the global dynamic range introduces severe risks: 1. <xhtml:strong>Port Exhaustion</xhtml:strong>: Under standard server load, limiting the global ephemeral range to a small number of ports can exhaust available sockets, resulting in network failures and domain isolation outages. 2. <xhtml:strong>Replication Failure</xhtml:strong>: High volumes of directory transactions can exhaust localized RPC ports. 3. <xhtml:strong>No Added Security Value</xhtml:strong>: Narrowing the dynamic range globally does not mitigate standard exploits, and endpoints communicate with local security authority protocols (LSAD/SAMR) over SMB named pipes (<xhtml:code>\PIPE\lsass</xhtml:code>) rather than directly via dynamic TCP sockets.</xhtml:p>
        <xhtml:p>Therefore, the system-wide dynamic RPC port range must remain at its default start port (<xhtml:code>49152</xhtml:code>) and number of ports (<xhtml:code>16384</xhtml:code>), and any narrowing configurations must be avoided.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Define Static Ports for NTDS and Netlogon via GPO Registry Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting Domain Controllers (e.g., <xhtml:code>GPO_Hardening_DC_RPC</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Define the following <xhtml:strong>Registry Items</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>NTDS Static Port</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\NTDS\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TCP/IP Port</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>38901</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Netlogon Static Port</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\Netlogon\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>DCTcpipPort</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>38902</xhtml:code> (Decimal)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Ensure System-Wide RPC Port Narrowing is Disabled</xhtml:h4>
        <xhtml:p>Ensure that the registry key <xhtml:code>HKLM\SOFTWARE\Microsoft\Rpc\Internet</xhtml:code> does <xhtml:strong>not</xhtml:strong> exist in your GPOs, as this key enforces restrictive dynamic range overrides. If present, delete the key to allow systems to fall back to the default Windows Server dynamic range (49152-65535).</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure the RPC static ports and restore default dynamic ranges.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-RPCDynamicPorts.ps1">Download Script: Set-RPCDynamicPorts.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-RPCDynamicPorts.ps1
# Description: Configures static RPC ports for NTDS, Netlogon, and DFSR, and ensures system-wide dynamic RPC ranges are at default values.

Write-Host "Configuring RPC dynamic port restrictions..." -ForegroundColor Cyan

$IsDC = (Get-CimInstance -ClassName Win32_ComputerSystem).Roles -contains "Primary_Domain_Controller"

if ($IsDC) {
    Write-Host "[+] Target is a Domain Controller. Configuring static ports..." -ForegroundColor Gray
    
    # NTDS Static Port -&gt; TCP 38901
    $NtdsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
    if (-not (Test-Path $NtdsPath)) {
        New-Item -Path $NtdsPath -Force | Out-Null
    }
    Set-ItemProperty -Path $NtdsPath -Name "TCP/IP Port" -Value 38901 -Type DWord
    Write-Host "    NTDS Static Port set to TCP 38901." -ForegroundColor Green
    
    # Netlogon Static Port -&gt; TCP 38902
    $NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"
    if (-not (Test-Path $NetlogonPath)) {
        New-Item -Path $NetlogonPath -Force | Out-Null
    }
    Set-ItemProperty -Path $NetlogonPath -Name "DCTcpipPort" -Value 38902 -Type DWord
    Write-Host "    Netlogon Static Port set to TCP 38902." -ForegroundColor Green

    # DFSR Static Port -&gt; TCP 5722 (if DFSR namespace is present)
    try {
        $DfsrConfig = Get-CimInstance -Namespace "root\MicrosoftDFS" -ClassName DfsrServiceConfiguration -ErrorAction Stop
        if ($null -ne $DfsrConfig) {
            Set-CimInstance -Query "Select * from DfsrServiceConfiguration" -Namespace "root\MicrosoftDFS" -Property @{ RpcPortAssignment = 5722 } -ErrorAction Stop | Out-Null
            Write-Host "    DFSR Static Replication Port set to TCP 5722." -ForegroundColor Green
        }
    } catch {
        Write-Host "    DFSR WMI configuration not accessible or role not installed. Skipping." -ForegroundColor Yellow
    }
}

# Ensure system-wide dynamic RPC range is at default (start=49152, num=16384)
# In accordance with Microsoft Directory Services guidelines to prevent port exhaustion.
Write-Host "[+] Resetting global dynamic RPC ports to default..." -ForegroundColor Gray

$ProcV4 = Start-Process netsh -ArgumentList "int ipv4 set dynamicport tcp start=49152 num=16384" -Wait -NoNewWindow -PassThru
if ($ProcV4.ExitCode -eq 0) {
    Write-Host "    IPv4 Dynamic Port Range reset to default (49152-65535)." -ForegroundColor Green
} else {
    Write-Error "    Failed to reset IPv4 dynamic port range."
}

$ProcV6 = Start-Process netsh -ArgumentList "int ipv6 set dynamicport tcp start=49152 num=16384" -Wait -NoNewWindow -PassThru
if ($ProcV6.ExitCode -eq 0) {
    Write-Host "    IPv6 Dynamic Port Range reset to default (49152-65535)." -ForegroundColor Green
} else {
    Write-Error "    Failed to reset IPv6 dynamic port range."
}

# Clean HKLM\SOFTWARE\Microsoft\Rpc\Internet range narrowing if present
$RpcInternetPath = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
if (Test-Path $RpcInternetPath) {
    Remove-Item -Path $RpcInternetPath -Force -Recurse | Out-Null
    Write-Host "    Removed restrictive RPC Internet registry settings to restore defaults." -ForegroundColor Green
}

Write-Host "RPC dynamic port configuration applied successfully." -ForegroundColor Cyan</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-RPCDynamicPorts.ps1">Download Script: Test-RPCDynamicPorts.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-RPCDynamicPorts.ps1
# Description: Audits dynamic RPC configurations and static ports.

Write-Host "Auditing dynamic RPC configurations..." -ForegroundColor Cyan

$IsDC = (Get-CimInstance -ClassName Win32_ComputerSystem).Roles -contains "Primary_Domain_Controller"
$vulnerable = $false

if ($IsDC) {
    # 1. NTDS Static Port Audit
    $NtdsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
    $NtdsVal = Get-ItemProperty -Path $NtdsPath -Name "TCP/IP Port" -ErrorAction SilentlyContinue
    $NtdsPort = if ($NtdsVal) { $NtdsVal."TCP/IP Port" } else { 0 }
    
    $NtdsColor = if ($NtdsPort -eq 38901) { "Green" } else { "Red"; $vulnerable = $true }
    Write-Host "    - NTDS Static Port: $($NtdsPort) (Expected = 38901)" -ForegroundColor $NtdsColor
    
    # 2. Netlogon Static Port Audit
    $NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"
    $NetlogonVal = Get-ItemProperty -Path $NetlogonPath -Name "DCTcpipPort" -ErrorAction SilentlyContinue
    $NetlogonPort = if ($NetlogonVal) { $NetlogonVal.DCTcpipPort } else { 0 }
    
    $NetlogonColor = if ($NetlogonPort -eq 38902) { "Green" } else { "Red"; $vulnerable = $true }
    Write-Host "    - Netlogon Static Port: $($NetlogonPort) (Expected = 38902)" -ForegroundColor $NetlogonColor

    # 3. DFSR Port Audit
    try {
        $DfsrConfig = Get-CimInstance -Namespace "root\MicrosoftDFS" -ClassName DfsrServiceConfiguration -ErrorAction Stop
        if ($null -ne $DfsrConfig) {
            $DfsrPort = $DfsrConfig.RpcPortAssignment
            $DfsrColor = if ($DfsrPort -eq 5722) { "Green" } else { "Red"; $vulnerable = $true }
            Write-Host "    - DFSR Replication Port: $($DfsrPort) (Expected = 5722)" -ForegroundColor $DfsrColor
        }
    } catch {
        Write-Host "    - DFSR role not active or WMI inaccessible." -ForegroundColor Gray
    }
}

# 4. Global Dynamic Port Audit (Netsh query)
Write-Host "[+] Querying active TCP dynamic port settings..." -ForegroundColor Yellow

$IPv4Ports = netsh int ipv4 show dynamicport tcp
$IPv6Ports = netsh int ipv6 show dynamicport tcp

Write-Host "--- IPv4 Dynamic Port Output ---" -ForegroundColor Gray
$IPv4Ports | Out-String | Write-Host -ForegroundColor DarkGray
Write-Host "--- IPv6 Dynamic Port Output ---" -ForegroundColor Gray
$IPv6Ports | Out-String | Write-Host -ForegroundColor DarkGray

# Verify if dynamic ranges are narrowed
$RpcInternetPath = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
if (Test-Path $RpcInternetPath) {
    Write-Host "[!] VULNERABLE: Restrictive RPC Internet registry settings found. Narrowing dynamic ranges is not recommended." -ForegroundColor Red
    $vulnerable = $true
} else {
    Write-Host "[+] Restrictive RPC Internet registry settings are absent." -ForegroundColor Green
}

if ($vulnerable) {
    Write-Host "Audit result: NON-COMPLIANT" -ForegroundColor Red
} else {
    Write-Host "Audit result: COMPLIANT" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-RPCDynamicPorts.ps1
# Description: Configures static RPC ports for NTDS, Netlogon, and DFSR, and ensures system-wide dynamic RPC ranges are at default values.

Write-Host "Configuring RPC dynamic port restrictions..." -ForegroundColor Cyan

$IsDC = (Get-CimInstance -ClassName Win32_ComputerSystem).Roles -contains "Primary_Domain_Controller"

if ($IsDC) {
    Write-Host "[+] Target is a Domain Controller. Configuring static ports..." -ForegroundColor Gray
    
    # NTDS Static Port -&gt; TCP 38901
    $NtdsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
    if (-not (Test-Path $NtdsPath)) {
        New-Item -Path $NtdsPath -Force | Out-Null
    }
    Set-ItemProperty -Path $NtdsPath -Name "TCP/IP Port" -Value 38901 -Type DWord
    Write-Host "    NTDS Static Port set to TCP 38901." -ForegroundColor Green
    
    # Netlogon Static Port -&gt; TCP 38902
    $NetlogonPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"
    if (-not (Test-Path $NetlogonPath)) {
        New-Item -Path $NetlogonPath -Force | Out-Null
    }
    Set-ItemProperty -Path $NetlogonPath -Name "DCTcpipPort" -Value 38902 -Type DWord
    Write-Host "    Netlogon Static Port set to TCP 38902." -ForegroundColor Green

    # DFSR Static Port -&gt; TCP 5722 (if DFSR namespace is present)
    try {
        $DfsrConfig = Get-CimInstance -Namespace "root\MicrosoftDFS" -ClassName DfsrServiceConfiguration -ErrorAction Stop
        if ($null -ne $DfsrConfig) {
            Set-CimInstance -Query "Select * from DfsrServiceConfiguration" -Namespace "root\MicrosoftDFS" -Property @{ RpcPortAssignment = 5722 } -ErrorAction Stop | Out-Null
            Write-Host "    DFSR Static Replication Port set to TCP 5722." -ForegroundColor Green
        }
    } catch {
        Write-Host "    DFSR WMI configuration not accessible or role not installed. Skipping." -ForegroundColor Yellow
    }
}

# Ensure system-wide dynamic RPC range is at default (start=49152, num=16384)
# In accordance with Microsoft Directory Services guidelines to prevent port exhaustion.
Write-Host "[+] Resetting global dynamic RPC ports to default..." -ForegroundColor Gray

$ProcV4 = Start-Process netsh -ArgumentList "int ipv4 set dynamicport tcp start=49152 num=16384" -Wait -NoNewWindow -PassThru
if ($ProcV4.ExitCode -eq 0) {
    Write-Host "    IPv4 Dynamic Port Range reset to default (49152-65535)." -ForegroundColor Green
} else {
    Write-Error "    Failed to reset IPv4 dynamic port range."
}

$ProcV6 = Start-Process netsh -ArgumentList "int ipv6 set dynamicport tcp start=49152 num=16384" -Wait -NoNewWindow -PassThru
if ($ProcV6.ExitCode -eq 0) {
    Write-Host "    IPv6 Dynamic Port Range reset to default (49152-65535)." -ForegroundColor Green
} else {
    Write-Error "    Failed to reset IPv6 dynamic port range."
}

# Clean HKLM\SOFTWARE\Microsoft\Rpc\Internet range narrowing if present
$RpcInternetPath = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
if (Test-Path $RpcInternetPath) {
    Remove-Item -Path $RpcInternetPath -Force -Recurse | Out-Null
    Write-Host "    Removed restrictive RPC Internet registry settings to restore defaults." -ForegroundColor Green
}

Write-Host "RPC dynamic port configuration applied successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-003] Configure Workstation and Server Isolation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations, Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-workstation-isolation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Once an adversary establishes initial access on a Tier 2 client workstation or a Member Server, they will attempt to move laterally across the network to identify high-value targets, harvest credentials, and locate Tier 0 administrative pathways.</xhtml:p>
        <xhtml:p>Lateral movement commonly relies on standard management and remote connection protocols, including SMB (TCP 445), RPC (TCP 135 and dynamic ports), RDP (TCP 3389), and WinRM (TCP 5985/5986). In a standard enterprise design, workstations do not require inbound connections from other workstations, and member servers rarely require inbound connections from peer member servers in the same tier.</xhtml:p>
        <xhtml:p>Configuring local firewalls via Group Policy to explicitly block inbound SMB, RPC, RDP, and WinRM traffic originating from peer subnets (while maintaining administrative exceptions from authorized management subnets and Domain Controllers) stops host-to-host lateral propagation and containment is maintained.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure Peer Isolation GPO Rules</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstation_Isolation</xhtml:code>) or Member Servers OU.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Under <xhtml:strong>Inbound Rules</xhtml:strong>, create new custom rules to block peer traffic:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 1: Block Inbound SMB from Peers</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>
            <xhtml:em>: `TCP` | </xhtml:em>
            <xhtml:em>Local Port</xhtml:em>*: <xhtml:code>445</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Remote Address</xhtml:em>*: <xhtml:code>[Insert Local Client / Peer Subnets, e.g., 10.20.0.0/16]</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain, Private</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 2: Block Inbound RDP from Peers</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>
            <xhtml:em>: `TCP` | </xhtml:em>
            <xhtml:em>Local Port</xhtml:em>*: <xhtml:code>3389</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Remote Address</xhtml:em>*: <xhtml:code>[Insert Local Client / Peer Subnets]</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain, Private</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 3: Block Inbound WinRM from Peers</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>
            <xhtml:em>: `TCP` | </xhtml:em>
            <xhtml:em>Local Port</xhtml:em>*: <xhtml:code>5985, 5986</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Remote Address</xhtml:em>*: <xhtml:code>[Insert Local Client / Peer Subnets]</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain, Private</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 4: Block Inbound RPC from Peers</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>
            <xhtml:em>: `TCP` | </xhtml:em>
            <xhtml:em>Local Port</xhtml:em>*: <xhtml:code>135, 49152-65535</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Remote Address</xhtml:em>*: <xhtml:code>[Insert Local Client / Peer Subnets]</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain, Private</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Create Management Allow Exceptions</xhtml:h4>
        <xhtml:p>In the same GPO, ensure there are priority inbound <xhtml:strong>Allow</xhtml:strong> rules configured to permit administration from dedicated administrative paths: <xhtml:em> </xhtml:em>
          <xhtml:em>Allow Inbound Administration</xhtml:em>
          <xhtml:em>: </xhtml:em>
          <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Allow the connection</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Protocol</xhtml:em>
          <xhtml:em>: `TCP` | </xhtml:em>
          <xhtml:em>Local Port</xhtml:em>
          <xhtml:em>: `445, 3389, 5985, 5986` </xhtml:em>
          <xhtml:strong>Remote Address</xhtml:strong>: <xhtml:code>[Insert Administrative Subnet (PAW / Jump Hosts), e.g., 10.10.0.0/24]</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain</xhtml:code>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and apply workstation/server isolation rules.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-WorkstationIsolation.ps1">Download Script: Set-WorkstationIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-WorkstationIsolation.ps1
# Configures local firewall rules to block inbound SMB, RPC, and RDP from peer subnets.
# Allows access only from designated Domain Controller and Admin Management subnets.

# Adjust subnets for your local environment
$AdminSubnet = "10.10.0.0/24"      # PAW / Jump Host / DC Subnet
$PeerSubnet = "10.20.0.0/16"       # Local client/member peer subnet

Write-Host "Applying Workstation and Server Isolation Firewall Rules..." -ForegroundColor Cyan

# 1. Enable firewall profiles
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True
Write-Host "All firewall profiles enabled." -ForegroundColor Green

# 2. Block Inbound SMB (TCP 445) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound SMB from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 445 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "SMB peer blocking rule created." -ForegroundColor Green

# 3. Block Inbound RDP (TCP 3389) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound RDP from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 3389 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "RDP peer blocking rule created." -ForegroundColor Green

# 4. Block Inbound WinRM (TCP 5985, 5986) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound WinRM from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort @(5985, 5986) `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "WinRM peer blocking rule created." -ForegroundColor Green

# 5. Block Inbound RPC (TCP 135) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound RPC Mapper from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 135 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "RPC Endpoint Mapper peer blocking rule created." -ForegroundColor Green

# 6. Allow Inbound Administration from Management Subnet (RDP, WinRM, SMB)
New-NetFirewallRule -DisplayName "Hardening: Allow Admin Management Inbound" `
    -Direction Inbound `
    -Action Allow `
    -Protocol TCP `
    -LocalPort @(445, 3389, 5985, 5986) `
    -RemoteAddress $AdminSubnet `
    -Profile Domain `
    -Enabled True | Out-Null
Write-Host "Management subnet inbound allowance rule created." -ForegroundColor Green

Write-Host "Workstation and Server isolation firewall rules applied successfully." -ForegroundColor Cyan</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-WorkstationIsolation.ps1">Download Script: Test-WorkstationIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-WorkstationIsolation.ps1
# Audits the presence of isolation blocking rules on local firewall profiles.

Write-Host "Auditing workstation and server peer isolation rules..." -ForegroundColor Cyan

$PortsToVerify = @(445, 3389, 135)
$FailedChecks = 0

foreach ($Port in $PortsToVerify) {
    # Query rules that block inbound traffic on specified ports
    $BlockRules = Get-NetFirewallRule -ErrorAction SilentlyContinue | Where-Object {
        $_.Direction -eq "Inbound" -and
        $_.Action -eq "Block" -and
        $_.Enabled -eq $true
    }
    
    $HasPortBlock = $false
    foreach ($Rule in $BlockRules) {
        # Check filter associated with the rule to resolve local port
        $Filter = Get-NetFirewallPortFilter -AssociatedNetFirewallRule $Rule -ErrorAction SilentlyContinue
        if ($Filter -and $Filter.LocalPort -eq [string]$Port) {
            $HasPortBlock = $true
        }
    }
    
    if ($HasPortBlock) {
        Write-Host "    - Isolation block rule for Port $($Port): FOUND (Compliant)" -ForegroundColor Green
    } else {
        Write-Host "    - Isolation block rule for Port $($Port): NOT FOUND (Non-Compliant)" -ForegroundColor Red
        $FailedChecks++
    }
}

if ($FailedChecks -eq 0) {
    Write-Host "Audit Result: Peer isolation firewall rules are verified." -ForegroundColor Green
} else {
    Write-Warning "Audit Result: Missing peer isolation rules detected!"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-WorkstationIsolation.ps1
# Configures local firewall rules to block inbound SMB, RPC, and RDP from peer subnets.
# Allows access only from designated Domain Controller and Admin Management subnets.

# Adjust subnets for your local environment
$AdminSubnet = "10.10.0.0/24"      # PAW / Jump Host / DC Subnet
$PeerSubnet = "10.20.0.0/16"       # Local client/member peer subnet

Write-Host "Applying Workstation and Server Isolation Firewall Rules..." -ForegroundColor Cyan

# 1. Enable firewall profiles
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True
Write-Host "All firewall profiles enabled." -ForegroundColor Green

# 2. Block Inbound SMB (TCP 445) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound SMB from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 445 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "SMB peer blocking rule created." -ForegroundColor Green

# 3. Block Inbound RDP (TCP 3389) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound RDP from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 3389 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "RDP peer blocking rule created." -ForegroundColor Green

# 4. Block Inbound WinRM (TCP 5985, 5986) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound WinRM from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort @(5985, 5986) `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "WinRM peer blocking rule created." -ForegroundColor Green

# 5. Block Inbound RPC (TCP 135) from peer subnet
New-NetFirewallRule -DisplayName "Hardening: Block Inbound RPC Mapper from Peers" `
    -Direction Inbound `
    -Action Block `
    -Protocol TCP `
    -LocalPort 135 `
    -RemoteAddress $PeerSubnet `
    -Profile Domain, Private `
    -Enabled True | Out-Null
Write-Host "RPC Endpoint Mapper peer blocking rule created." -ForegroundColor Green

# 6. Allow Inbound Administration from Management Subnet (RDP, WinRM, SMB)
New-NetFirewallRule -DisplayName "Hardening: Allow Admin Management Inbound" `
    -Direction Inbound `
    -Action Allow `
    -Protocol TCP `
    -LocalPort @(445, 3389, 5985, 5986) `
    -RemoteAddress $AdminSubnet `
    -Profile Domain `
    -Enabled True | Out-Null
Write-Host "Management subnet inbound allowance rule created." -ForegroundColor Green

Write-Host "Workstation and Server isolation firewall rules applied successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-004" severity="medium" weight="10.0" selected="false">
      <title>[REQ-NET-004] Configure IPsec Domain Isolation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, PAWs, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-ipsec-domain-isolation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In environments without hardware-enforced line-encryption, an attacker who gains physical or logical access to internal network switches can perform Man-in-the-Middle (MitM) attacks (e.g., ARP spoofing, DHCP spoofing) or passive packet sniffing.</xhtml:p>
        <xhtml:p>Implementing IPsec Transport Mode using Connection Security Rules ensures that domain-joined hosts cryptographically authenticate each other before transmitting payloads.</xhtml:p>
        <xhtml:p>Benefits of IPsec isolation include: 1. <xhtml:strong>Host Authentication</xhtml:strong>: Ensures only trusted, domain-joined systems communicating via Kerberos V5 or certificates can exchange packets with critical servers. 2. <xhtml:strong>Data Integrity &amp; Confidentiality</xhtml:strong>: Prevents packet tampering and sniffing on the wire. For DC-to-DC replication, mandating ESP encryption secures highly sensitive directory updates. 3. <xhtml:strong>Mitigation of Relay Attacks</xhtml:strong>: Even if credentials are intercepted, they cannot be easily replayed to services protected by IPsec isolation rules.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To implement domain isolation successfully, two separate GPO policies must be created and linked: one targeting standard Endpoints (Member Servers and Workstations) and one targeting Domain Controllers.</xhtml:p>
        <xhtml:h4>1. Endpoint Domain Isolation GPO (Isolated Domain)</xhtml:h4>
        <xhtml:p>This GPO targets all standard domain assets (Workstations, Member Servers, PAWs).</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting the target OUs (e.g., <xhtml:code>GPO_Hardening_IPsec_Isolation_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Connection Security Rules</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create the general Isolation Rule:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>Connection Security Rules</xhtml:em>
            <xhtml:em> and select </xhtml:em>
            <xhtml:em>New Rule...</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Isolation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Requirements</xhtml:em>*: Select <xhtml:code>Request authentication for inbound and outbound connections</xhtml:code> (to allow cleartext fallback).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Authentication Method</xhtml:em>*: <xhtml:code>Computer (Kerberos V5)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>Hardening: IPsec Domain Isolation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure Boot Exemptions (to prevent lockouts):</xhtml:li>
          <xhtml:li>Create a new rule for essential infrastructure services:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Exemption</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>IP Addresses</xhtml:em>*: Add the IP addresses of your DHCP servers and DNS servers (if external or required for initial boot name resolution).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>Hardening: IPsec Infrastructure Exemptions</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:p>
          <xhtml:em>Note: Domain Controllers must </xhtml:em>
          <xhtml:em>not</xhtml:em>
          <xhtml:em> be added to the exemption list. If DCs are exempted, all endpoint-to-DC traffic will bypass IPsec entirely. Instead, by keeping DCs subject to the general rule with `Request outbound` requirements, clients can fall back to cleartext during boot to obtain a Kerberos ticket, and will automatically establish an encrypted IPsec SA for all subsequent DC communications once authenticated. Once the domain isolation environment is stable and all domain assets have active SAs, the GPO requirement for endpoints can be upgraded to `Require authentication for inbound connections and request authentication for outbound connections`.</xhtml:em>
        </xhtml:p>
        <xhtml:h4>2. Domain Controller IPsec GPO</xhtml:h4>
        <xhtml:p>This GPO targets only the Domain Controllers OU. Because DCs must process bootstrap authentication from unjoined or booting machines, they cannot require IPsec for client access.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting the Domain Controllers OU (e.g., <xhtml:code>GPO_Hardening_IPsec_DCs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to Connection Security Rules.</xhtml:li>
          <xhtml:li>Create the DC Client Access Rule:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Isolation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Requirements</xhtml:em>*: <xhtml:code>Request authentication for inbound and outbound connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Authentication Method</xhtml:em>*: <xhtml:code>Computer (Kerberos V5)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: <xhtml:code>Domain</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>Hardening: IPsec DC Client Access</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create the DC-to-DC Replication Encryption Rule:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Isolation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Requirements</xhtml:em>*: <xhtml:code>Require authentication for inbound and outbound connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Authentication Method</xhtml:em>*: <xhtml:code>Computer (Kerberos V5)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocols and Ports</xhtml:em>*: Set protocol to <xhtml:code>TCP</xhtml:code>, local port to <xhtml:code>49152-65535</xhtml:code> (or your restricted RPC port, e.g., <xhtml:code>50000-50100</xhtml:code>).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>
            <xhtml:em>: Under advanced settings, require </xhtml:em>
            <xhtml:em>ESP encryption</xhtml:em>* for this connection rule.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>Hardening: IPsec DC-to-DC Replication</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and configure Connection Security Rules.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-IPsecDomainIsolation.ps1">Download Script: Set-IPsecDomainIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-IPsecDomainIsolation.ps1
# Configures local IPsec Connection Security Rules for Domain Isolation.
# Detects role (DC vs Endpoint) and applies appropriate isolation policies.

Write-Host "Configuring IPsec Connection Security Rules..." -ForegroundColor Cyan

# 1. Determine local machine role (Domain Controller vs Endpoint/Member Server)
$IsDomainController = $false
try {
    $ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
    if ($ComputerSystem.DomainRole -eq 4 -or $ComputerSystem.DomainRole -eq 5) {
        $IsDomainController = $true
    }
} catch {
    # Fallback to checking NTDS service or environment variables if CimInstance fails
    if (Get-Service -Name NTDS -ErrorAction SilentlyContinue) {
        $IsDomainController = $true
    }
}

if ($IsDomainController) {
    Write-Host "Local system identified as a Domain Controller." -ForegroundColor Yellow
    
    # Define Rule Names
    $GeneralRuleName = "Hardening: IPsec DC Client Access"
    $DCDCRuleName = "Hardening: IPsec DC-to-DC Replication"
    
    # A. DC General Client Access Rule: Inbound/Outbound set to Request
    # Allows initial cleartext bootstrap (Kerberos, DNS, LDAP) for clients, then promotes to IPsec
    $ExistingGeneral = Get-NetIPsecRule -DisplayName $GeneralRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingGeneral) {
        New-NetIPsecRule -DisplayName $GeneralRuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Created general DC IPsec rule (Request mode)." -ForegroundColor Green
    } else {
        Set-NetIPsecRule -DisplayName $GeneralRuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Updated general DC IPsec rule (Request mode)." -ForegroundColor Gray
    }
    
    # B. DC-to-DC Replication Rule: Require authentication and require encryption
    # Targets replication ports or remote DC subnets
    $ExistingDCDC = Get-NetIPsecRule -DisplayName $DCDCRuleName -ErrorAction SilentlyContinue
    
    # Attempt to retrieve other DCs in the domain for remote IP targeting
    $DCIps = @()
    try {
        if (Get-Module -ListAvailable -Name ActiveDirectory) {
            Import-Module ActiveDirectory -ErrorAction Stop
            $DCIps = Get-ADDomainController -Filter * | Where-Object { $_.IPv4Address -ne (Get-NetIPAddress -AddressFamily IPv4 | Select-Object -ExpandProperty IPAddress) } | Select-Object -ExpandProperty IPv4Address
        }
    } catch {
        Write-Host "Could not query AD for other DC IP addresses. Rule will apply generally to replication ports." -ForegroundColor Yellow
    }
    
    # Configure the rule targeting replication traffic (TCP 49152-65535 or custom RPC)
    # Require authentication (forces IPsec) for DC-to-DC communication
    $Params = @{
        DisplayName = $DCDCRuleName
        InboundSecurity = "Require"
        OutboundSecurity = "Require"
        Phase1AuthSet = "ComputerKerberos"
        Protocol = "TCP"
        LocalPort = "49152-65535"
        Enabled = "True"
    }
    if ($DCIps.Count -gt 0) {
        $Params["RemoteAddress"] = $DCIps
    }
    
    if ($null -eq $ExistingDCDC) {
        New-NetIPsecRule @Params | Out-Null
        Write-Host "Created DC-to-DC replication encryption rule (Require mode)." -ForegroundColor Green
    } else {
        # RemoteAddress cannot be passed empty if we update, so omit if empty
        if ($null -eq $Params["RemoteAddress"]) {
            Set-NetIPsecRule -DisplayName $DCDCRuleName `
                -InboundSecurity Require `
                -OutboundSecurity Require `
                -Phase1AuthSet "ComputerKerberos" `
                -Protocol TCP `
                -LocalPort "49152-65535" `
                -Enabled True | Out-Null
        } else {
            Set-NetIPsecRule @Params | Out-Null
        }
        Write-Host "Updated DC-to-DC replication encryption rule (Require mode)." -ForegroundColor Gray
    }
} else {
    Write-Host "Local system identified as an Endpoint/Member Server." -ForegroundColor Yellow
    
    $RuleName = "Hardening: IPsec Domain Isolation"
    $ExistingRule = Get-NetIPsecRule -DisplayName $RuleName -ErrorAction SilentlyContinue
    
    # Endpoints: Request inbound and Request outbound for safe deployment, 
    # then promote to Require inbound and Request outbound (fallback to cleartext for DCs/Internet)
    if ($null -eq $ExistingRule) {
        New-NetIPsecRule -DisplayName $RuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Created general Endpoint IPsec rule (Request mode)." -ForegroundColor Green
    } else {
        Set-NetIPsecRule -DisplayName $RuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Updated general Endpoint IPsec rule (Request mode)." -ForegroundColor Gray
    }
    
    # Create Exemption Rules for DHCP and DNS to prevent boot lockouts
    $DHCPRuleName = "Exempt: DHCP Traffic"
    $DNSRuleName = "Exempt: DNS Traffic"
    
    # DHCP Rule (UDP 67, 68)
    $ExistingDHCP = Get-NetIPsecRule -DisplayName $DHCPRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingDHCP) {
        New-NetIPsecRule -DisplayName $DHCPRuleName `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol UDP `
            -LocalPort @("67", "68") `
            -Enabled True | Out-Null
        Write-Host "Created DHCP exemption rule." -ForegroundColor Green
    }
    
    # DNS Rule (UDP/TCP 53)
    $ExistingDNS = Get-NetIPsecRule -DisplayName $DNSRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingDNS) {
        New-NetIPsecRule -DisplayName $DNSRuleName `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol UDP `
            -RemotePort "53" `
            -Enabled True | Out-Null
        New-NetIPsecRule -DisplayName "$DNSRuleName (TCP)" `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol TCP `
            -RemotePort "53" `
            -Enabled True | Out-Null
        Write-Host "Created DNS exemption rules." -ForegroundColor Green
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-IPsecDomainIsolation.ps1">Download Script: Test-IPsecDomainIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-IPsecDomainIsolation.ps1
# Checks the state of local IPsec Connection Security Rules.
# Accounts for role-specific rules (DC vs Endpoint).

Write-Host "Auditing IPsec Connection Security Rules..." -ForegroundColor Cyan

# 1. Determine local machine role
$IsDomainController = $false
try {
    $ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
    if ($ComputerSystem.DomainRole -eq 4 -or $ComputerSystem.DomainRole -eq 5) {
        $IsDomainController = $true
    }
} catch {
    if (Get-Service -Name NTDS -ErrorAction SilentlyContinue) {
        $IsDomainController = $true
    }
}

$NonCompliant = $false

if ($IsDomainController) {
    Write-Host "Auditing Domain Controller IPsec rules..." -ForegroundColor Yellow
    
    # DC should have a Client Access rule set to Request (or better)
    $GeneralRule = Get-NetIPsecRule -DisplayName "Hardening: IPsec DC Client Access" -ErrorAction SilentlyContinue
    if ($null -eq $GeneralRule -or $GeneralRule.Enabled -ne $true) {
        Write-Host "    - General DC IPsec rule: NOT FOUND or DISABLED (Non-Compliant)" -ForegroundColor Red
        $NonCompliant = $true
    } else {
        $InboundSec = $GeneralRule.InboundSecurity
        $OutboundSec = $GeneralRule.OutboundSecurity
        if ($InboundSec -ne "Request" -and $InboundSec -ne "Require") {
            Write-Host "    - General DC IPsec Inbound Security is '$InboundSec' (Non-Compliant, should be Request)" -ForegroundColor Red
            $NonCompliant = $true
        } else {
            Write-Host "    - General DC IPsec Inbound Security: $InboundSec (Compliant)" -ForegroundColor Green
        }
    }
    
    # DC should have a DC-to-DC replication rule set to Require
    $DCDCRule = Get-NetIPsecRule -DisplayName "Hardening: IPsec DC-to-DC Replication" -ErrorAction SilentlyContinue
    if ($null -eq $DCDCRule -or $DCDCRule.Enabled -ne $true) {
        Write-Host "    - DC-to-DC Replication rule: NOT FOUND or DISABLED (Non-Compliant)" -ForegroundColor Red
        $NonCompliant = $true
    } else {
        $InboundSec = $DCDCRule.InboundSecurity
        $OutboundSec = $DCDCRule.OutboundSecurity
        if ($InboundSec -ne "Require" -or $OutboundSec -ne "Require") {
            Write-Host "    - DC-to-DC IPsec Inbound/Outbound is '$InboundSec'/'$OutboundSec' (Non-Compliant, should be Require)" -ForegroundColor Red
            $NonCompliant = $true
        } else {
            Write-Host "    - DC-to-DC IPsec rule: Require (Compliant)" -ForegroundColor Green
        }
    }
} else {
    Write-Host "Auditing Endpoint/Member Server IPsec rules..." -ForegroundColor Yellow
    
    # Endpoint should have a general Domain Isolation rule set to Request (transition) or Require (inbound) / Request (outbound)
    $GeneralRule = Get-NetIPsecRule -DisplayName "Hardening: IPsec Domain Isolation" -ErrorAction SilentlyContinue
    if ($null -eq $GeneralRule -or $GeneralRule.Enabled -ne $true) {
        Write-Host "    - Endpoint Domain Isolation rule: NOT FOUND or DISABLED (Non-Compliant)" -ForegroundColor Red
        $NonCompliant = $true
    } else {
        $InboundSec = $GeneralRule.InboundSecurity
        $OutboundSec = $GeneralRule.OutboundSecurity
        
        # Request/Request or Require/Request are acceptable depending on transition phase
        if ($InboundSec -eq "None" -or $OutboundSec -eq "None") {
            Write-Host "    - Endpoint Domain Isolation is set to None (Non-Compliant)" -ForegroundColor Red
            $NonCompliant = $true
        } else {
            Write-Host "    - Endpoint Domain Isolation rule: Enabled (Inbound: $InboundSec, Outbound: $OutboundSec) (Compliant)" -ForegroundColor Green
        }
    }
    
    # DHCP and DNS exemptions should be configured if outbound is strict
    $DHCPRule = Get-NetIPsecRule -DisplayName "Exempt: DHCP Traffic" -ErrorAction SilentlyContinue
    if ($null -eq $DHCPRule) {
        Write-Host "    - DHCP Exemption rule: NOT FOUND (Warning: highly recommended to prevent DHCP issues)" -ForegroundColor Yellow
    } else {
        Write-Host "    - DHCP Exemption rule: FOUND (Compliant)" -ForegroundColor Green
    }
    
    $DNSRule = Get-NetIPsecRule -DisplayName "Exempt: DNS Traffic" -ErrorAction SilentlyContinue
    if ($null -eq $DNSRule) {
        Write-Host "    - DNS Exemption rule: NOT FOUND (Warning: highly recommended to prevent DNS name resolution failures during boot)" -ForegroundColor Yellow
    } else {
        Write-Host "    - DNS Exemption rule: FOUND (Compliant)" -ForegroundColor Green
    }
}

if ($NonCompliant) {
    Write-Host "IPsec Domain Isolation Audit: Non-Compliant." -ForegroundColor Red
    exit 1
} else {
    Write-Host "IPsec Domain Isolation Audit: Compliant." -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-IPsecDomainIsolation.ps1
# Configures local IPsec Connection Security Rules for Domain Isolation.
# Detects role (DC vs Endpoint) and applies appropriate isolation policies.

Write-Host "Configuring IPsec Connection Security Rules..." -ForegroundColor Cyan

# 1. Determine local machine role (Domain Controller vs Endpoint/Member Server)
$IsDomainController = $false
try {
    $ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
    if ($ComputerSystem.DomainRole -eq 4 -or $ComputerSystem.DomainRole -eq 5) {
        $IsDomainController = $true
    }
} catch {
    # Fallback to checking NTDS service or environment variables if CimInstance fails
    if (Get-Service -Name NTDS -ErrorAction SilentlyContinue) {
        $IsDomainController = $true
    }
}

if ($IsDomainController) {
    Write-Host "Local system identified as a Domain Controller." -ForegroundColor Yellow
    
    # Define Rule Names
    $GeneralRuleName = "Hardening: IPsec DC Client Access"
    $DCDCRuleName = "Hardening: IPsec DC-to-DC Replication"
    
    # A. DC General Client Access Rule: Inbound/Outbound set to Request
    # Allows initial cleartext bootstrap (Kerberos, DNS, LDAP) for clients, then promotes to IPsec
    $ExistingGeneral = Get-NetIPsecRule -DisplayName $GeneralRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingGeneral) {
        New-NetIPsecRule -DisplayName $GeneralRuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Created general DC IPsec rule (Request mode)." -ForegroundColor Green
    } else {
        Set-NetIPsecRule -DisplayName $GeneralRuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Updated general DC IPsec rule (Request mode)." -ForegroundColor Gray
    }
    
    # B. DC-to-DC Replication Rule: Require authentication and require encryption
    # Targets replication ports or remote DC subnets
    $ExistingDCDC = Get-NetIPsecRule -DisplayName $DCDCRuleName -ErrorAction SilentlyContinue
    
    # Attempt to retrieve other DCs in the domain for remote IP targeting
    $DCIps = @()
    try {
        if (Get-Module -ListAvailable -Name ActiveDirectory) {
            Import-Module ActiveDirectory -ErrorAction Stop
            $DCIps = Get-ADDomainController -Filter * | Where-Object { $_.IPv4Address -ne (Get-NetIPAddress -AddressFamily IPv4 | Select-Object -ExpandProperty IPAddress) } | Select-Object -ExpandProperty IPv4Address
        }
    } catch {
        Write-Host "Could not query AD for other DC IP addresses. Rule will apply generally to replication ports." -ForegroundColor Yellow
    }
    
    # Configure the rule targeting replication traffic (TCP 49152-65535 or custom RPC)
    # Require authentication (forces IPsec) for DC-to-DC communication
    $Params = @{
        DisplayName = $DCDCRuleName
        InboundSecurity = "Require"
        OutboundSecurity = "Require"
        Phase1AuthSet = "ComputerKerberos"
        Protocol = "TCP"
        LocalPort = "49152-65535"
        Enabled = "True"
    }
    if ($DCIps.Count -gt 0) {
        $Params["RemoteAddress"] = $DCIps
    }
    
    if ($null -eq $ExistingDCDC) {
        New-NetIPsecRule @Params | Out-Null
        Write-Host "Created DC-to-DC replication encryption rule (Require mode)." -ForegroundColor Green
    } else {
        # RemoteAddress cannot be passed empty if we update, so omit if empty
        if ($null -eq $Params["RemoteAddress"]) {
            Set-NetIPsecRule -DisplayName $DCDCRuleName `
                -InboundSecurity Require `
                -OutboundSecurity Require `
                -Phase1AuthSet "ComputerKerberos" `
                -Protocol TCP `
                -LocalPort "49152-65535" `
                -Enabled True | Out-Null
        } else {
            Set-NetIPsecRule @Params | Out-Null
        }
        Write-Host "Updated DC-to-DC replication encryption rule (Require mode)." -ForegroundColor Gray
    }
} else {
    Write-Host "Local system identified as an Endpoint/Member Server." -ForegroundColor Yellow
    
    $RuleName = "Hardening: IPsec Domain Isolation"
    $ExistingRule = Get-NetIPsecRule -DisplayName $RuleName -ErrorAction SilentlyContinue
    
    # Endpoints: Request inbound and Request outbound for safe deployment, 
    # then promote to Require inbound and Request outbound (fallback to cleartext for DCs/Internet)
    if ($null -eq $ExistingRule) {
        New-NetIPsecRule -DisplayName $RuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Created general Endpoint IPsec rule (Request mode)." -ForegroundColor Green
    } else {
        Set-NetIPsecRule -DisplayName $RuleName `
            -InboundSecurity Request `
            -OutboundSecurity Request `
            -Phase1AuthSet "ComputerKerberos" `
            -Enabled True | Out-Null
        Write-Host "Updated general Endpoint IPsec rule (Request mode)." -ForegroundColor Gray
    }
    
    # Create Exemption Rules for DHCP and DNS to prevent boot lockouts
    $DHCPRuleName = "Exempt: DHCP Traffic"
    $DNSRuleName = "Exempt: DNS Traffic"
    
    # DHCP Rule (UDP 67, 68)
    $ExistingDHCP = Get-NetIPsecRule -DisplayName $DHCPRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingDHCP) {
        New-NetIPsecRule -DisplayName $DHCPRuleName `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol UDP `
            -LocalPort @("67", "68") `
            -Enabled True | Out-Null
        Write-Host "Created DHCP exemption rule." -ForegroundColor Green
    }
    
    # DNS Rule (UDP/TCP 53)
    $ExistingDNS = Get-NetIPsecRule -DisplayName $DNSRuleName -ErrorAction SilentlyContinue
    if ($null -eq $ExistingDNS) {
        New-NetIPsecRule -DisplayName $DNSRuleName `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol UDP `
            -RemotePort "53" `
            -Enabled True | Out-Null
        New-NetIPsecRule -DisplayName "$DNSRuleName (TCP)" `
            -InboundSecurity None `
            -OutboundSecurity None `
            -Protocol TCP `
            -RemotePort "53" `
            -Enabled True | Out-Null
        Write-Host "Created DNS exemption rules." -ForegroundColor Green
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-005] Harden IPsec Cryptographic Configurations</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, PAWs, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Baseline Tiering &amp; Sensitivity</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Tier 0 Domain Controllers &amp; PAWs</xhtml:strong>: Must strictly enforce modern cryptographic algorithms (AES-256, SHA-256/384, ECDH Group 19/20) with no legacy fallbacks permitted.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Tier 1 Member Servers &amp; Tier 2 Endpoints</xhtml:strong>: Standard baseline mandates AES-256 and ECDH Group 19/20. Fallback to DH Group 14 (2048-bit MODP) and AES-CBC 256 is permitted solely for systems communicating with legacy appliances or boundary hosts (<xhtml:strong>[REQ-NET-004]</xhtml:strong>).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/harden-ipsec-cryptography.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Internet Protocol Security (IPsec) is the foundational cryptographic framework that underpins domain isolation (<xhtml:strong>[REQ-NET-004]</xhtml:strong>) and line-encryption across Active Directory networks. However, default IPsec settings in legacy Windows environments permit outdated cryptographic primitives, including 3DES, DES, MD5, SHA-1, and Diffie-Hellman Groups 1, 2, and 5. These algorithms are mathematically broken or provide insufficient security margins against modern adversaries.</xhtml:p>
        <xhtml:p>Hardening IPsec cryptographic parameters mitigates multiple specific threat vectors:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Open the GPO Editor</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting the target systems (e.g., <xhtml:code>GPO_Hardening_IPsec_Cryptography</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security - [LDAP]</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Windows Defender Firewall with Advanced Security - [LDAP]</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select the <xhtml:strong>IPsec Settings</xhtml:strong> tab.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Key Exchange (Main Mode) Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under <xhtml:strong>IPsec defaults</xhtml:strong>, click <xhtml:strong>Customize...</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Under <xhtml:strong>Key exchange (Main Mode)</xhtml:strong>, select <xhtml:strong>Advanced</xhtml:strong>, then click <xhtml:strong>Customize...</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Security methods</xhtml:strong> list in priority order:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Proposal 1 (Preferred)</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Integrity</xhtml:em>*: <xhtml:code>SHA-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Encryption</xhtml:em>*: <xhtml:code>AES-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key exchange algorithm</xhtml:em>*: <xhtml:code>Elliptic Curve Diffie-Hellman Group 19</xhtml:code> (P-256)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Proposal 2</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Integrity</xhtml:em>*: <xhtml:code>SHA-384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Encryption</xhtml:em>*: <xhtml:code>AES-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key exchange algorithm</xhtml:em>*: <xhtml:code>Elliptic Curve Diffie-Hellman Group 20</xhtml:code> (P-384)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Proposal 3 (Compatibility Fallback)</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Integrity</xhtml:em>*: <xhtml:code>SHA-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Encryption</xhtml:em>*: <xhtml:code>AES-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key exchange algorithm</xhtml:em>*: <xhtml:code>Diffie-Hellman Group 14</xhtml:code> (2048-bit)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>Remove all entries referencing DES, 3DES, MD5, SHA-1, or DH Groups 1, 2, and 5.*</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Key lifetimes</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minutes</xhtml:em>*: Set to <xhtml:code>480</xhtml:code> (8 hours).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Sessions</xhtml:em>*: Set to <xhtml:code>0</xhtml:code> (unlimited within time window).</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Diffie-Hellman</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select </xhtml:em>
            <xhtml:em>Force Diffie-Hellman</xhtml:em>* (ensures DH recalculation upon rekeying).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Configure Data Protection (Quick Mode) Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under <xhtml:strong>Data protection (Quick Mode)</xhtml:strong>, select <xhtml:strong>Advanced</xhtml:strong>, then click <xhtml:strong>Customize...</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Check <xhtml:strong>Require encryption for all connection security rules that use these settings</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Data integrity and encryption</xhtml:strong> rules:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 1 (AEAD Preferred)</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>*: <xhtml:code>ESP</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Encryption</xhtml:em>*: <xhtml:code>AES-GCM 256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Integrity</xhtml:em>*: <xhtml:code>None</xhtml:code> (GMAC is integrated directly into GCM mode)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule 2 (Standard CBC)</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol</xhtml:em>*: <xhtml:code>ESP</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Encryption</xhtml:em>*: <xhtml:code>AES-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Integrity</xhtml:em>*: <xhtml:code>SHA-256</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>Remove any entries referencing DES, 3DES, MD5, or SHA-1.*</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Key lifetimes</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Data amount</xhtml:em>*: Set to <xhtml:code>100000</xhtml:code> KB (100 MB).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Time</xhtml:em>*: Set to <xhtml:code>60</xhtml:code> minutes.</xhtml:li>
          <xhtml:li>Under <xhtml:strong>Perfect Forward Secrecy (PFS)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Use Diffie-Hellman for data protection (PFS)</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key exchange algorithm</xhtml:em>*: Select <xhtml:code>Elliptic Curve Diffie-Hellman Group 19</xhtml:code> (or <xhtml:code>Same as Main Mode</xhtml:code>).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Configure Authentication Method Defaults</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under <xhtml:strong>Authentication method</xhtml:strong>, select <xhtml:strong>Advanced</xhtml:strong>, then click <xhtml:strong>Customize...</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Configure authentication priorities:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>First authentication method</xhtml:em>
            <xhtml:em>: Select </xhtml:em>
            <xhtml:em>Computer (Kerberos V5)</xhtml:em>* (Standard for domain-joined hosts).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Second authentication method / Fallback</xhtml:em>
            <xhtml:em>: Select </xhtml:em>
            <xhtml:em>Computer certificate</xhtml:em>*, specify the enterprise Root/Intermediate CA, and configure criteria to match machine certificates (RSA &gt;= 3072 bits or ECDSA P-256).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>Ensure Pre-Shared Key (PSK) authentication is strictly prohibited in enterprise production environments.*</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>5. Configure Global IPsec Exemptions and Certificate Validation</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under <xhtml:strong>IPsec exemptions</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Exempt ICMP from IPsec</xhtml:em>*: Select <xhtml:code>No</xhtml:code> (dictates that ICMP traffic must be authenticated and encrypted along with standard traffic, closing covert channels).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to close the IPsec Defaults dialog.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong> on the Windows Defender Firewall Properties window.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-IPsecCryptography.ps1
# Description: Configures hardened IPsec Main Mode, Quick Mode, and Global Firewall cryptographic parameters.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding()]
param()

Write-Host "Configuring hardened IPsec cryptographic settings..." -ForegroundColor Cyan

# Phase 1: Define Main Mode cryptographic proposals
# Proposals mandate AES-256 encryption, SHA-256/SHA-384 hashing, and ECDH Group 19/20 or DH14 key exchange.
# Weak suites (DES, 3DES, MD5, SHA-1, DH Groups 1, 2, 5) are strictly excluded.
$MMProposals = @(
    (New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH19),
    (New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA384 -KeyExchange DH20),
    (New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH14)
)

# Manage Main Mode Crypto Set
$MMSetName = "Hardened_MM_CryptoSet"
$ExistingMM = Get-NetIPsecMainModeCryptoSet -DisplayName $MMSetName -ErrorAction SilentlyContinue

if ($null -eq $ExistingMM) {
    New-NetIPsecMainModeCryptoSet -DisplayName $MMSetName `
        -Proposal $MMProposals `
        -MaxMinutes 480 `
        -MaxSessions 0 `
        -ForceDiffieHellman $true | Out-Null
    Write-Host "Created Main Mode crypto set '$($MMSetName)'." -ForegroundColor Green
} else {
    Set-NetIPsecMainModeCryptoSet -DisplayName $MMSetName `
        -Proposal $MMProposals `
        -MaxMinutes 480 `
        -MaxSessions 0 `
        -ForceDiffieHellman $true | Out-Null
    Write-Host "Updated Main Mode crypto set '$($MMSetName)'." -ForegroundColor Gray
}

# Phase 2: Define Quick Mode cryptographic proposals
# Primary: ESP AES-GCM 256 (Authenticated Encryption with Associated Data - AEAD)
# Secondary: ESP AES-256 with SHA-256 integrity
$QMProposals = @(
    (New-NetIPsecQuickModeCryptoProposal -Encapsulation ESP -Encryption AESGCM256 -ESPHash None -MaxKilobytes 100000 -MaxMinutes 60),
    (New-NetIPsecQuickModeCryptoProposal -Encapsulation ESP -Encryption AES256 -ESPHash SHA256 -MaxKilobytes 100000 -MaxMinutes 60)
)

# Manage Quick Mode Crypto Set with Perfect Forward Secrecy (PFS) enforced
$QMSetName = "Hardened_QM_CryptoSet"
$ExistingQM = Get-NetIPsecQuickModeCryptoSet -DisplayName $QMSetName -ErrorAction SilentlyContinue

if ($null -eq $ExistingQM) {
    New-NetIPsecQuickModeCryptoSet -DisplayName $QMSetName `
        -Proposal $QMProposals `
        -PerfectForwardSecrecyGroup DH19 | Out-Null
    Write-Host "Created Quick Mode crypto set '$($QMSetName)' with PFS (DH19)." -ForegroundColor Green
} else {
    Set-NetIPsecQuickModeCryptoSet -DisplayName $QMSetName `
        -Proposal $QMProposals `
        -PerfectForwardSecrecyGroup DH19 | Out-Null
    Write-Host "Updated Quick Mode crypto set '$($QMSetName)' with PFS (DH19)." -ForegroundColor Gray
}

# Phase 3: Configure Global IPsec Firewall Settings
# Enforces CRL revocation checking for computer certificates, bounds idle time, and restricts exemptions.
try {
    Set-NetFirewallSetting -CertValidationLevel RequireCrlCheck `
        -MaxSAIdleTimeSeconds 300 `
        -Exemptions NeighborDiscovery,Dhcp `
        -ErrorAction Stop | Out-Null
    Write-Host "Configured global firewall IPsec settings (RequireCrlCheck, IdleTime: 300s, Exemptions: ND/DHCP)." -ForegroundColor Green
} catch {
    Write-Host "Warning: Could not update global firewall settings: $($_.Exception.Message)" -ForegroundColor Yellow
}

# Phase 4: Associate cryptographic sets with local Connection Security Rules and Main Mode Rules
$Rules = Get-NetIPsecRule -ErrorAction SilentlyContinue
if ($null -ne $Rules -and $Rules.Count -gt 0) {
    foreach ($Rule in $Rules) {
        # Only bind QuickModeCryptoSet if the rule is not an Exemption rule (InboundSecurity -ne None)
        if ($Rule.InboundSecurity -ne "None" -or $Rule.OutboundSecurity -ne "None") {
            Set-NetIPsecRule -DisplayName $Rule.DisplayName -QuickModeCryptoSet $QMSetName -ErrorAction SilentlyContinue | Out-Null
            Write-Host "Associated '$($QMSetName)' with rule '$($Rule.DisplayName)'." -ForegroundColor Gray
        }
    }
} else {
    Write-Host "No active Connection Security Rules found to bind." -ForegroundColor Gray
}

$MMRules = Get-NetIPsecMainModeRule -ErrorAction SilentlyContinue
if ($null -ne $MMRules -and $MMRules.Count -gt 0) {
    foreach ($MMRule in $MMRules) {
        Set-NetIPsecMainModeRule -DisplayName $MMRule.DisplayName -MainModeCryptoSet $MMSetName -ErrorAction SilentlyContinue | Out-Null
        Write-Host "Associated '$($MMSetName)' with Main Mode rule '$($MMRule.DisplayName)'." -ForegroundColor Gray
    }
} else {
    Write-Host "No active Main Mode Rules found to bind." -ForegroundColor Gray
}

Write-Host "IPsec cryptography hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-006] Harden TLS Protocols, Cipher Suites, and Elliptic Curves</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, PAWs, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/harden-tls-configuration.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Legacy versions of SSL (2.0 and 3.0) and TLS (1.0 and 1.1) are cryptographically weak and vulnerable to various attacks (such as BEAST, POODLE, and SWEET32) that can lead to credential exposure and session hijacking. Domain services, including LDAPS and WinRM, must enforce the usage of TLS 1.2 and TLS 1.3 (where supported) to prevent protocol downgrade attacks.</xhtml:p>
        <xhtml:p>In addition to disabling insecure protocol versions, the TLS cipher suites and Elliptic Curves must be restricted to modern, collision-resistant options. CBC (Cipher Block Chaining) mode and RC4 ciphers are prone to padding oracle attacks. Restricting configurations to AES-GCM (Galois/Counter Mode) authenticated encryption suites combined with strong Elliptic Curve Diffie-Hellman (ECDHE) curves (such as Curve25519 and NIST P-384) guarantees confidentiality, integrity, and perfect forward secrecy (PFS).</xhtml:p>
        <xhtml:p>By default, legacy .NET Framework applications (targeting .NET 3.5 or earlier) and WinHTTP-based APIs do not enforce TLS 1.2 or TLS 1.3, potentially defaulting to weak protocols like SSL 3.0 or TLS 1.0. Enabling <xhtml:code>SchUseStrongCrypto</xhtml:code> and <xhtml:code>SystemDefaultTlsVersions</xhtml:code> forces .NET to use the system default secure TLS versions. Restricting <xhtml:code>DefaultSecureProtocols</xhtml:code> forces WinHTTP clients to use TLS 1.2. Disabling the strong-name bypass (<xhtml:code>AllowStrongNameBypass</xhtml:code> = <xhtml:code>0</xhtml:code>) prevents full-trust assemblies from skipping signature validation, protecting the .NET runtime from loading tampered assemblies.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Enforce SSL Cipher Suite Order and ECC Curve Order via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting all domain assets (e.g., <xhtml:code>GPO_Hardening_TLS_Schannel</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\SSL Configuration Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click the <xhtml:strong>SSL Cipher Suite Order</xhtml:strong> policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set the policy to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> In the </xhtml:em>
            <xhtml:em>SSL Cipher Suites</xhtml:em>* text box, enter the hardened comma-separated cipher suite string:</xhtml:li>
          <xhtml:li>
            <xhtml:code>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click the <xhtml:strong>ECC Curve Order</xhtml:strong> policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set the policy to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> In the </xhtml:em>
            <xhtml:em>ECC Curves</xhtml:em>* text box, enter the curves in order of preference:</xhtml:li>
          <xhtml:li>
            <xhtml:code>curve25519,nistP384,nistP256</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Deploy Schannel Protocol Registry settings via GPO Preferences</xhtml:h4>
        <xhtml:p>Since Schannel protocol versions (disabling TLS 1.0/1.1 and enabling TLS 1.2/1.3) are not exposed via default ADMX templates, configure them using <xhtml:strong>Registry Preferences</xhtml:strong>: 1. Within the same GPO, navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code> 2. Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>. 3. Create registry values under: <xhtml:code>HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols</xhtml:code> 4. Configure key pairs for each protocol (<xhtml:code>SSL 2.0</xhtml:code>, <xhtml:code>SSL 3.0</xhtml:code>, <xhtml:code>TLS 1.0</xhtml:code>, <xhtml:code>TLS 1.1</xhtml:code>, <xhtml:code>TLS 1.2</xhtml:code>, <xhtml:code>TLS 1.3</xhtml:code>) under both <xhtml:code>Client</xhtml:code> and <xhtml:code>Server</xhtml:code> subkeys: <xhtml:em> </xhtml:em>
          <xhtml:em>To Disable (SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1)</xhtml:em>
          <xhtml:em>: </xhtml:em> Value Name: <xhtml:code>Enabled</xhtml:code> | Type: <xhtml:code>REG_DWORD</xhtml:code> | Value Data: <xhtml:code>0</xhtml:code>
          <xhtml:em> Value Name: `DisabledByDefault` | Type: `REG_DWORD` | Value Data: `1` </xhtml:em>
          <xhtml:strong>To Enable (TLS 1.2, TLS 1.3)</xhtml:strong>: <xhtml:em> Value Name: `Enabled` | Type: `REG_DWORD` | Value Data: `1` </xhtml:em> Value Name: <xhtml:code>DisabledByDefault</xhtml:code> | Type: <xhtml:code>REG_DWORD</xhtml:code> | Value Data: <xhtml:code>0</xhtml:code>
        </xhtml:p>
        <xhtml:p>
          <xhtml:em>Note: Systems must be rebooted for Schannel protocol and cipher settings to take effect.</xhtml:em>
        </xhtml:p>
        <xhtml:h4>3. Deploy .NET and WinHTTP Registry Settings via GPO Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Within the same GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following registry entries (as Registry Items):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>.NET 4.0 (32-bit &amp; 64-bit)</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319</xhtml:code> | Value: <xhtml:code>SchUseStrongCrypto</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319</xhtml:code> | Value: <xhtml:code>SystemDefaultTlsVersions</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319</xhtml:code> | Value: <xhtml:code>SchUseStrongCrypto</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319</xhtml:code> | Value: <xhtml:code>SystemDefaultTlsVersions</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>.NET 2.0 (32-bit &amp; 64-bit)</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\.NETFramework\v2.0.50727</xhtml:code> | Value: <xhtml:code>SchUseStrongCrypto</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\.NETFramework\v2.0.50727</xhtml:code> | Value: <xhtml:code>SystemDefaultTlsVersions</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727</xhtml:code> | Value: <xhtml:code>SchUseStrongCrypto</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727</xhtml:code> | Value: <xhtml:code>SystemDefaultTlsVersions</xhtml:code> = <xhtml:code>1</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>.NET Strong-Name Bypass</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\.NETFramework</xhtml:code> | Value: <xhtml:code>AllowStrongNameBypass</xhtml:code> = <xhtml:code>0</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework</xhtml:code> | Value: <xhtml:code>AllowStrongNameBypass</xhtml:code> = <xhtml:code>0</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>WinHTTP (32-bit &amp; 64-bit)</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp</xhtml:code> | Value: <xhtml:code>DefaultSecureProtocols</xhtml:code> = <xhtml:code>2048</xhtml:code> (REG_DWORD)</xhtml:li>
          <xhtml:li>* Key: <xhtml:code>HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp</xhtml:code> | Value: <xhtml:code>DefaultSecureProtocols</xhtml:code> = <xhtml:code>2048</xhtml:code> (REG_DWORD)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on testing hosts or non-GPO-managed systems.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-TLSConfiguration.ps1">Download Script: Set-TLSConfiguration.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-TLSConfiguration.ps1
# Description: Hardens TLS/Schannel protocols, prioritizes modern cipher suites, and orders ECC curves.

Write-Host "Configuring Schannel protocols, cipher suites, and ECC curves..." -ForegroundColor Cyan

# Define Protocols to disable
$ProtocolsToDisable = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
# Define Protocols to enable
$ProtocolsToEnable = @("TLS 1.2", "TLS 1.3")

# 1. Configure Protocols
$SchannelRoot = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"

foreach ($Proto in $ProtocolsToDisable) {
    $Subkeys = @("Client", "Server")
    foreach ($Subkey in $Subkeys) {
        $Path = "$($SchannelRoot)\$($Proto)\$($Subkey)"
        if (-not (Test-Path $Path)) {
            New-Item -Path $Path -Force | Out-Null
        }
        Set-ItemProperty -Path $Path -Name "Enabled" -Value 0 -Type DWord -Force | Out-Null
        Set-ItemProperty -Path $Path -Name "DisabledByDefault" -Value 1 -Type DWord -Force | Out-Null
    }
}

foreach ($Proto in $ProtocolsToEnable) {
    $Subkeys = @("Client", "Server")
    foreach ($Subkey in $Subkeys) {
        $Path = "$($SchannelRoot)\$($Proto)\$($Subkey)"
        if (-not (Test-Path $Path)) {
            New-Item -Path $Path -Force | Out-Null
        }
        Set-ItemProperty -Path $Path -Name "Enabled" -Value 1 -Type DWord -Force | Out-Null
        Set-ItemProperty -Path $Path -Name "DisabledByDefault" -Value 0 -Type DWord -Force | Out-Null
    }
}

# 2. Configure SSL Cipher Suite Order and ECC Curve Order Policy
$SSLConfigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
if (-not (Test-Path $SSLConfigPath)) {
    New-Item -Path $SSLConfigPath -Force | Out-Null
}

# Define cipher suites list
$CipherSuites = @(
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
)

# Define ECC curves list
$EccCurves = @(
    "curve25519",
    "nistP384",
    "nistP256"
)

# Apply policy properties
Set-ItemProperty -Path $SSLConfigPath -Name "Functions" -Value $CipherSuites -Type MultiString -Force | Out-Null
Set-ItemProperty -Path $SSLConfigPath -Name "EccCurves" -Value $EccCurves -Type MultiString -Force | Out-Null

# 3. Configure .NET strong cryptography, strong-name bypass, and WinHTTP TLS
$RegistryTargets = @(
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048; Type = "DWord" }
)

foreach ($target in $RegistryTargets) {
    if (-not (Test-Path $target.Path)) {
        New-Item -Path $target.Path -Force | Out-Null
    }
    Set-ItemProperty -Path $target.Path -Name $target.Name -Value $target.Value -Type $target.Type -Force | Out-Null
}

Write-Host "Schannel configuration applied. A system reboot is required to apply changes." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-TLSConfiguration.ps1">Download Script: Test-TLSConfiguration.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-TLSConfiguration.ps1
# Description: Audits TLS/Schannel protocol configuration, cipher suites, and ECC curves.

Write-Host "Auditing TLS and Cryptographic configurations..." -ForegroundColor Cyan

$NonCompliantCount = 0
$SchannelRoot = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"

# 1. Audit Protocols
$ProtocolsToDisable = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
foreach ($Proto in $ProtocolsToDisable) {
    $Subkeys = @("Client", "Server")
    foreach ($Subkey in $Subkeys) {
        $Path = "$($SchannelRoot)\$($Proto)\$($Subkey)"
        if (Test-Path $Path) {
            $Enabled = Get-ItemPropertyValue -Path $Path -Name "Enabled" -ErrorAction SilentlyContinue
            if ($Enabled -ne 0) {
                Write-Host "    - Protocol $($Proto) ($($Subkey)) is not disabled (Non-Compliant)." -ForegroundColor Red
                $NonCompliantCount++
            } else {
                Write-Host "    - Protocol $($Proto) ($($Subkey)) is disabled (Compliant)." -ForegroundColor Green
            }
        } else {
            Write-Host "    - Protocol $($Proto) ($($Subkey)) registry key does not exist (Compliant)." -ForegroundColor Green
        }
    }
}

# 2. Audit SSL Policy and ECC Curves
$SSLConfigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
if (Test-Path $SSLConfigPath) {
    $Functions = Get-ItemPropertyValue -Path $SSLConfigPath -Name "Functions" -ErrorAction SilentlyContinue
    $EccCurves = Get-ItemPropertyValue -Path $SSLConfigPath -Name "EccCurves" -ErrorAction SilentlyContinue

    if ($null -eq $Functions -or $Functions.Length -eq 0) {
        Write-Host "    - SSL Cipher Suite order policy is not configured (Non-Compliant)." -ForegroundColor Red
        $NonCompliantCount++
    } else {
        if ($Functions[0] -match "GCM") {
            Write-Host "    - SSL Cipher Suite priority matches standards (Compliant)." -ForegroundColor Green
        } else {
            Write-Host "    - SSL Cipher Suite priority does not favor secure GCM suites first (Non-Compliant)." -ForegroundColor Red
            $NonCompliantCount++
        }
    }

    if ($null -eq $EccCurves -or $EccCurves.Length -eq 0) {
        Write-Host "    - ECC Curve priority policy is not configured (Non-Compliant)." -ForegroundColor Red
        $NonCompliantCount++
    } else {
        if ($EccCurves[0] -eq "curve25519" -or $EccCurves[0] -eq "nistP384") {
            Write-Host "    - ECC Curve priority matches standards (Compliant)." -ForegroundColor Green
        } else {
            Write-Host "    - ECC Curve priority does not favor curve25519/nistP384 (Non-Compliant)." -ForegroundColor Red
            $NonCompliantCount++
        }
    }
} else {
    Write-Host "    - Custom SSL configuration policies are not configured (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
}

# 3. Audit .NET and WinHTTP registry configurations
$RegistryAudits = @(
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1 }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1 }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0 }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048 }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048 }
)

foreach ($target in $RegistryAudits) {
    if (Test-Path $target.Path) {
        $val = Get-ItemPropertyValue -Path $target.Path -Name $target.Name -ErrorAction SilentlyContinue
        if ($val -eq $target.Value) {
            Write-Host "    - Registry Setting: $($target.Path)\$($target.Name) is Compliant." -ForegroundColor Green
        } else {
            Write-Host "    - Registry Setting: $($target.Path)\$($target.Name) is Non-Compliant (Actual: '$val', Expected: '$($target.Value)')." -ForegroundColor Red
            $NonCompliantCount++
        }
    } else {
        Write-Host "    - Registry Key: $($target.Path) does not exist (Non-Compliant)." -ForegroundColor Red
        $NonCompliantCount++
    }
}

if ($NonCompliantCount -eq 0) {
    Write-Host "TLS and Cryptographic configuration: Compliant." -ForegroundColor Green
} else {
    Write-Host "TLS and Cryptographic configuration: Non-Compliant ($($NonCompliantCount) issue(s) detected)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-TLSConfiguration.ps1
# Description: Hardens TLS/Schannel protocols, prioritizes modern cipher suites, and orders ECC curves.

Write-Host "Configuring Schannel protocols, cipher suites, and ECC curves..." -ForegroundColor Cyan

# Define Protocols to disable
$ProtocolsToDisable = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
# Define Protocols to enable
$ProtocolsToEnable = @("TLS 1.2", "TLS 1.3")

# 1. Configure Protocols
$SchannelRoot = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"

foreach ($Proto in $ProtocolsToDisable) {
    $Subkeys = @("Client", "Server")
    foreach ($Subkey in $Subkeys) {
        $Path = "$($SchannelRoot)\$($Proto)\$($Subkey)"
        if (-not (Test-Path $Path)) {
            New-Item -Path $Path -Force | Out-Null
        }
        Set-ItemProperty -Path $Path -Name "Enabled" -Value 0 -Type DWord -Force | Out-Null
        Set-ItemProperty -Path $Path -Name "DisabledByDefault" -Value 1 -Type DWord -Force | Out-Null
    }
}

foreach ($Proto in $ProtocolsToEnable) {
    $Subkeys = @("Client", "Server")
    foreach ($Subkey in $Subkeys) {
        $Path = "$($SchannelRoot)\$($Proto)\$($Subkey)"
        if (-not (Test-Path $Path)) {
            New-Item -Path $Path -Force | Out-Null
        }
        Set-ItemProperty -Path $Path -Name "Enabled" -Value 1 -Type DWord -Force | Out-Null
        Set-ItemProperty -Path $Path -Name "DisabledByDefault" -Value 0 -Type DWord -Force | Out-Null
    }
}

# 2. Configure SSL Cipher Suite Order and ECC Curve Order Policy
$SSLConfigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
if (-not (Test-Path $SSLConfigPath)) {
    New-Item -Path $SSLConfigPath -Force | Out-Null
}

# Define cipher suites list
$CipherSuites = @(
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
)

# Define ECC curves list
$EccCurves = @(
    "curve25519",
    "nistP384",
    "nistP256"
)

# Apply policy properties
Set-ItemProperty -Path $SSLConfigPath -Name "Functions" -Value $CipherSuites -Type MultiString -Force | Out-Null
Set-ItemProperty -Path $SSLConfigPath -Name "EccCurves" -Value $EccCurves -Type MultiString -Force | Out-Null

# 3. Configure .NET strong cryptography, strong-name bypass, and WinHTTP TLS
$RegistryTargets = @(
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SchUseStrongCrypto"; Value = 1; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Name = "SystemDefaultTlsVersions"; Value = 1; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework"; Name = "AllowStrongNameBypass"; Value = 0; Type = "DWord" }
    
    @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048; Type = "DWord" }
    @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DefaultSecureProtocols"; Value = 2048; Type = "DWord" }
)

foreach ($target in $RegistryTargets) {
    if (-not (Test-Path $target.Path)) {
        New-Item -Path $target.Path -Force | Out-Null
    }
    Set-ItemProperty -Path $target.Path -Name $target.Name -Value $target.Value -Type $target.Type -Force | Out-Null
}

Write-Host "Schannel configuration applied. A system reboot is required to apply changes." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-007" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-007] Enforce SMBv3 Security and Digitally Sign/Encrypt Communications</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, PAWs, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/enforce-smbv3-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Server Message Block (SMB) version 1.0 (SMBv1) is obsolete, highly insecure, and vulnerable to critical exploits (such as MS17-010 / EternalBlue, which enabled the global spread of WannaCry and NotPetya). SMBv2, while newer, lacks modern cryptographic protection and is prone to Man-in-the-Middle (MitM) interception and NTLM relaying.</xhtml:p>
        <xhtml:p>Enforcing SMBv3 (minimum version 3.0.0 or 3.1.1) provides significant security advantages: 1. <xhtml:strong>AES-GCM Encryption</xhtml:strong>: Protects data in transit from passive sniffing and tampering. Enforcing encryption is critical on Domain Controllers (specifically for Sysvol and Netlogon shares) and servers hosting sensitive business files. 2. <xhtml:strong>Pre-Authentication Integrity</xhtml:strong>: Prevents tampering with SMB negotiation packets (mitigating downgrade attacks). 3. <xhtml:strong>SMB Signing</xhtml:strong>: Adds a cryptographic signature to all packets. Mandating SMB signing (specifically <xhtml:code>Digitally sign communications (always)</xhtml:code>) protects against SMB Relay attacks, where an attacker intercepts a NTLM authentication hash on the local network and replays it to a target server to gain unauthorized access.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure SMB Signing Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting all domain assets (e.g., <xhtml:code>GPO_Hardening_SMB_Security</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following four policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network client: Digitally sign communications (always)</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network client: Digitally sign communications (if server agrees)</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Digitally sign communications (always)</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Digitally sign communications (if client agrees)</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Mandate Minimum SMB Dialects</xhtml:h4>
        <xhtml:p>On systems that support ADMX templates for SMB dialects (Windows 11 / Server 2022+): 1. Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Network\Lanman Server</xhtml:code> 2. Double-click <xhtml:strong>Mandate the minimum version of SMB</xhtml:strong>: <xhtml:em> Set the policy to </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em>. </xhtml:em> Set the minimum version to <xhtml:code>SMB 3.0.0</xhtml:code> (or <xhtml:code>SMB 3.1.1</xhtml:code> to require the latest dialect). 3. Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Network\Lanman Workstation</xhtml:code> 4. Double-click <xhtml:strong>Mandate the minimum version of SMB</xhtml:strong>: <xhtml:em> Set the policy to </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em>. </xhtml:em> Set the minimum version to <xhtml:code>SMB 3.0.0</xhtml:code> (or <xhtml:code>SMB 3.1.1</xhtml:code>).</xhtml:p>
        <xhtml:h4>3. Disable SMBv1 Driver via GPO Preferences</xhtml:h4>
        <xhtml:p>To ensure the SMBv1 driver is disabled on older machines, deploy a registry change: 1. Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code> 2. Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>: <xhtml:em> </xhtml:em>
          <xhtml:em>Action</xhtml:em>
          <xhtml:em>: `Update` </xhtml:em>
          <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Key Path</xhtml:em>
          <xhtml:em>: `SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters` </xhtml:em>
          <xhtml:strong>Value name</xhtml:strong>: <xhtml:code>SMB1</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Value type</xhtml:em>
          <xhtml:em>: `REG_DWORD` </xhtml:em>
          <xhtml:strong>Value data</xhtml:strong>: <xhtml:code>0</xhtml:code>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enforce SMBv3 standards.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-SMBSecurity.ps1">Download Script: Set-SMBSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-SMBSecurity.ps1
# Description: Disables SMBv1, mandates signing, sets SMBv3 as minimum dialect, and enforces encryption.

Write-Host "Enforcing SMBv3 security settings..." -ForegroundColor Cyan

# 1. Disable SMBv1 Protocol globally (Server side)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Confirm:$false | Out-Null
Write-Host "SMBv1 server protocol disabled." -ForegroundColor Green

# 2. Disable SMBv1 Driver (Windows Optional Feature)
$SMB1Feature = Get-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -ErrorAction SilentlyContinue
if ($null -ne $SMB1Feature -and $SMB1Feature.State -eq "Enabled") {
    Disable-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -NoRestart -WarningAction SilentlyContinue | Out-Null
    Write-Host "SMB1 optional feature disabled." -ForegroundColor Green
}

# 3. Configure SMB Signing &amp; Encryption on Server
Set-SmbServerConfiguration -RequireSecuritySignature $true -EncryptData $true -Confirm:$false | Out-Null
Write-Host "SMB Server signing and encryption mandated." -ForegroundColor Green

# 4. Configure SMB Signing &amp; Encryption on Client
Set-SmbClientConfiguration -RequireSecuritySignature $true -Confirm:$false | Out-Null
Write-Host "SMB Client signing mandated." -ForegroundColor Green

# 5. Enforce Minimum Dialects in Registry (Server and Client)
$ServerParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$ClientParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters"

# Write minimum dialect version 0x00000300 (SMB 3.0.0)
if (-not (Test-Path $ServerParamsPath)) {
    New-Item -Path $ServerParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $ServerParamsPath -Name "MinSMB2Dialect" -Value 0x00000300 -Type DWord -Force | Out-Null

if (-not (Test-Path $ClientParamsPath)) {
    New-Item -Path $ClientParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientParamsPath -Name "MinSMB2Dialect" -Value 0x00000300 -Type DWord -Force | Out-Null

# Disable legacy fallback protocols (e.g. NetBIOS over TCP/IP) if possible, but keep focus on SMBv3
Write-Host "SMBv3 minimum dialect rules configured." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-SMBSecurity.ps1">Download Script: Test-SMBSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-SMBSecurity.ps1
# Description: Audits local SMB configuration for signing, encryption, and dialects.

Write-Host "Auditing SMB security configuration..." -ForegroundColor Cyan

$NonCompliantCount = 0

# Retrieve configurations
$ServerConfig = Get-SmbServerConfiguration
$ClientConfig = Get-SmbClientConfiguration

# 1. Audit SMBv1 Server status
if ($ServerConfig.EnableSMB1Protocol -eq $true) {
    Write-Host "    - SMBv1 Server protocol is enabled (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
} else {
    Write-Host "    - SMBv1 Server protocol is disabled (Compliant)." -ForegroundColor Green
}

# 2. Audit Signing Requirements
if ($ServerConfig.RequireSecuritySignature -ne $true) {
    Write-Host "    - SMB Server signing is not required (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
} else {
    Write-Host "    - SMB Server signing is mandated (Compliant)." -ForegroundColor Green
}

if ($ClientConfig.RequireSecuritySignature -ne $true) {
    Write-Host "    - SMB Client signing is not required (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
} else {
    Write-Host "    - SMB Client signing is mandated (Compliant)." -ForegroundColor Green
}

# 3. Audit Encryption Requirements
if ($ServerConfig.EncryptData -ne $true) {
    Write-Host "    - SMB Server global data encryption is not enforced (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
} else {
    Write-Host "    - SMB Server global data encryption is enforced (Compliant)." -ForegroundColor Green
}

# 4. Audit Registry Dialects
$ServerParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$ClientParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters"

if (Test-Path $ServerParamsPath) {
    $ServerMinDialect = Get-ItemPropertyValue -Path $ServerParamsPath -Name "MinSMB2Dialect" -ErrorAction SilentlyContinue
    if ($null -eq $ServerMinDialect -or $ServerMinDialect -lt 0x00000300) {
        Write-Host "    - Server minimum dialect is less than SMB 3.0 or not set (Non-Compliant)." -ForegroundColor Red
        $NonCompliantCount++
    } else {
        Write-Host "    - Server minimum dialect is set to SMB 3.0+ (Compliant)." -ForegroundColor Green
    }
} else {
    Write-Host "    - LanmanServer registry path is missing (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
}

if (Test-Path $ClientParamsPath) {
    $ClientMinDialect = Get-ItemPropertyValue -Path $ClientParamsPath -Name "MinSMB2Dialect" -ErrorAction SilentlyContinue
    if ($null -eq $ClientMinDialect -or $ClientMinDialect -lt 0x00000300) {
        Write-Host "    - Client minimum dialect is less than SMB 3.0 or not set (Non-Compliant)." -ForegroundColor Red
        $NonCompliantCount++
    } else {
        Write-Host "    - Client minimum dialect is set to SMB 3.0+ (Compliant)." -ForegroundColor Green
    }
} else {
    Write-Host "    - LanmanWorkstation registry path is missing (Non-Compliant)." -ForegroundColor Red
    $NonCompliantCount++
}

if ($NonCompliantCount -eq 0) {
    Write-Host "SMB Security configuration: Compliant." -ForegroundColor Green
} else {
    Write-Host "SMB Security configuration: Non-Compliant ($($NonCompliantCount) issue(s) detected)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-SMBSecurity.ps1
# Description: Disables SMBv1, mandates signing, sets SMBv3 as minimum dialect, and enforces encryption.

Write-Host "Enforcing SMBv3 security settings..." -ForegroundColor Cyan

# 1. Disable SMBv1 Protocol globally (Server side)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Confirm:$false | Out-Null
Write-Host "SMBv1 server protocol disabled." -ForegroundColor Green

# 2. Disable SMBv1 Driver (Windows Optional Feature)
$SMB1Feature = Get-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -ErrorAction SilentlyContinue
if ($null -ne $SMB1Feature -and $SMB1Feature.State -eq "Enabled") {
    Disable-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -NoRestart -WarningAction SilentlyContinue | Out-Null
    Write-Host "SMB1 optional feature disabled." -ForegroundColor Green
}

# 3. Configure SMB Signing &amp; Encryption on Server
Set-SmbServerConfiguration -RequireSecuritySignature $true -EncryptData $true -Confirm:$false | Out-Null
Write-Host "SMB Server signing and encryption mandated." -ForegroundColor Green

# 4. Configure SMB Signing &amp; Encryption on Client
Set-SmbClientConfiguration -RequireSecuritySignature $true -Confirm:$false | Out-Null
Write-Host "SMB Client signing mandated." -ForegroundColor Green

# 5. Enforce Minimum Dialects in Registry (Server and Client)
$ServerParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$ClientParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters"

# Write minimum dialect version 0x00000300 (SMB 3.0.0)
if (-not (Test-Path $ServerParamsPath)) {
    New-Item -Path $ServerParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $ServerParamsPath -Name "MinSMB2Dialect" -Value 0x00000300 -Type DWord -Force | Out-Null

if (-not (Test-Path $ClientParamsPath)) {
    New-Item -Path $ClientParamsPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientParamsPath -Name "MinSMB2Dialect" -Value 0x00000300 -Type DWord -Force | Out-Null

# Disable legacy fallback protocols (e.g. NetBIOS over TCP/IP) if possible, but keep focus on SMBv3
Write-Host "SMBv3 minimum dialect rules configured." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4007" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-008" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-008] Configure Firewall Logging and Operational Settings</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-firewall-logging.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Defender Firewall with Advanced Security (WFAS) serves as the host-level stateful firewall protecting Active Directory resources from unauthorized network access. However, without correct logging and behavioral configuration, the firewall does not provide adequate defensive or diagnostic value:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Visibility Gaps</xhtml:strong>: By default, Windows Defender Firewall does not log dropped packets. If logging is disabled, security administrators cannot detect failed connection attempts, reconnaissance scans (port scanning), or unauthorized network communications.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Log Rotational Coverage</xhtml:strong>: The default firewall log size limit of 4096 KB (4 MB) is insufficient for enterprise environments. High volumes of traffic or network scanning will cause the log to roll over rapidly, destroying valuable historical entries needed for security audits and incident investigation.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Deterministic Administrative Control</xhtml:strong>: Allowing local administrators to create local rules or local connection security rules (IPsec) on critical Tier 0 systems, such as Domain Controllers, risks bypassing centrally defined domain firewall GPOs. Restricting rule merging ensures a uniform security baseline.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Behavioral Notification Control</xhtml:strong>: Disabling interactive firewall notifications prevents desktop alerts from prompting administrative users, reducing operational noise and social engineering opportunities.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_Firewall_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Windows Defender Firewall with Advanced Security</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Under the <xhtml:strong>Domain Profile</xhtml:strong> tab, configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>State</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>
            <xhtml:em>, click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow unicast response</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code> (Set to <xhtml:code>No</xhtml:code> for Domain Controllers GPOs; set to <xhtml:code>Yes</xhtml:code> or <xhtml:code>No</xhtml:code> for Member Servers/Workstations depending on operational requirements)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code> (Set to <xhtml:code>No</xhtml:code> for Domain Controllers GPOs; set to <xhtml:code>Yes</xhtml:code> or <xhtml:code>No</xhtml:code> for Member Servers/Workstations depending on operational requirements)</xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>OK</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>
            <xhtml:em>, click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\LogFiles\Firewall\pfirewall.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>32768</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>OK</xhtml:em>*.</xhtml:li>
          <xhtml:li>Repeat the exact configuration steps (Step 5) for the <xhtml:strong>Private Profile</xhtml:strong> and <xhtml:strong>Public Profile</xhtml:strong> tabs.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target assets.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for testing or standalone systems) or if the control is not manageable via standard GPO GUI interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-FirewallLoggingAndSettings.ps1">Download Script: Set-FirewallLoggingAndSettings.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-FirewallLoggingAndSettings.ps1
# Description: Configures Windows Defender Firewall settings, log size, and log permissions for all profiles.

Write-Host "Applying Windows Defender Firewall hardening settings..." -ForegroundColor Cyan

# 1. Detect if the local system is a Domain Controller (ProductType = 2 is Domain Controller)
$IsDomainController = $false
$OSInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue
if ($null -ne $OSInfo) {
    if ($OSInfo.ProductType -eq 2) {
        $IsDomainController = $true
    }
}

# 2. Configure Domain, Private, and Public profiles
$Profiles = @("Domain", "Private", "Public")

foreach ($FwProfile in $Profiles) {
    Write-Host "Configuring Profile: $($FwProfile)..." -ForegroundColor Cyan
    
    # Enable firewall and set default inbound/outbound behavior and notifications
    Set-NetFirewallProfile -Profile $FwProfile `
                           -Enabled True `
                           -DefaultInboundAction Block `
                           -DefaultOutboundAction Allow `
                           -NotifyOnListen False `
                           -AllowUnicastResponseToMulticast True | Out-Null
                           
    # Configure logging: log dropped packets, disable successful logs, set size to 32MB (32768 KB)
    Set-NetFirewallProfile -Profile $FwProfile `
                           -LogBlocked True `
                           -LogAllowed False `
                           -LogMaxSizeKilobytes 32768 `
                           -LogFileName "%SystemRoot%\System32\LogFiles\Firewall\pfirewall.log" | Out-Null
                           
    # Disable local rule merging only on Domain Controllers to prevent bypasses
    if ($IsDomainController) {
        Set-NetFirewallProfile -Profile $FwProfile `
                               -AllowLocalFirewallRules False `
                               -AllowLocalIPsecRules False | Out-Null
        Write-Host "Disabled local rule merging on DC for profile: $($FwProfile)" -ForegroundColor Green
    } else {
        Set-NetFirewallProfile -Profile $FwProfile `
                               -AllowLocalFirewallRules True `
                               -AllowLocalIPsecRules True | Out-Null
        Write-Host "Configured profile: $($FwProfile) with local rule merging allowed" -ForegroundColor Green
    }
}

Write-Host "Firewall logging and operational settings configuration completed successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-FirewallLoggingAndSettingsStatus.ps1">Download Script: Get-FirewallLoggingAndSettingsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-FirewallLoggingAndSettingsStatus.ps1
Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction, NotifyOnListen, LogBlocked, LogAllowed, LogMaxSizeKilobytes, LogFileName, AllowLocalFirewallRules, AllowLocalIPsecRules</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-FirewallLoggingAndSettings.ps1
# Description: Configures Windows Defender Firewall settings, log size, and log permissions for all profiles.

Write-Host "Applying Windows Defender Firewall hardening settings..." -ForegroundColor Cyan

# 1. Detect if the local system is a Domain Controller (ProductType = 2 is Domain Controller)
$IsDomainController = $false
$OSInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue
if ($null -ne $OSInfo) {
    if ($OSInfo.ProductType -eq 2) {
        $IsDomainController = $true
    }
}

# 2. Configure Domain, Private, and Public profiles
$Profiles = @("Domain", "Private", "Public")

foreach ($FwProfile in $Profiles) {
    Write-Host "Configuring Profile: $($FwProfile)..." -ForegroundColor Cyan
    
    # Enable firewall and set default inbound/outbound behavior and notifications
    Set-NetFirewallProfile -Profile $FwProfile `
                           -Enabled True `
                           -DefaultInboundAction Block `
                           -DefaultOutboundAction Allow `
                           -NotifyOnListen False `
                           -AllowUnicastResponseToMulticast True | Out-Null
                           
    # Configure logging: log dropped packets, disable successful logs, set size to 32MB (32768 KB)
    Set-NetFirewallProfile -Profile $FwProfile `
                           -LogBlocked True `
                           -LogAllowed False `
                           -LogMaxSizeKilobytes 32768 `
                           -LogFileName "%SystemRoot%\System32\LogFiles\Firewall\pfirewall.log" | Out-Null
                           
    # Disable local rule merging only on Domain Controllers to prevent bypasses
    if ($IsDomainController) {
        Set-NetFirewallProfile -Profile $FwProfile `
                               -AllowLocalFirewallRules False `
                               -AllowLocalIPsecRules False | Out-Null
        Write-Host "Disabled local rule merging on DC for profile: $($FwProfile)" -ForegroundColor Green
    } else {
        Set-NetFirewallProfile -Profile $FwProfile `
                               -AllowLocalFirewallRules True `
                               -AllowLocalIPsecRules True | Out-Null
        Write-Host "Configured profile: $($FwProfile) with local rule merging allowed" -ForegroundColor Green
    }
}

Write-Host "Firewall logging and operational settings configuration completed successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4008" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-009" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-009] Configure Hardened UNC Paths and LDAP Client Signing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-hardened-unc-paths.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory clients and servers routinely query Domain Controllers to retrieve Group Policy Objects (GPOs), startup/shutdown scripts, and user logon scripts from the <xhtml:code>SYSVOL</xhtml:code> and <xhtml:code>NETLOGON</xhtml:code> shares. By default, these connections are made over standard UNC paths and do not strictly enforce integrity validation (SMB signing) or mutual authentication.</xhtml:p>
        <xhtml:p>Enforcing these channel-level controls mitigates the following threat vectors: 1. <xhtml:strong>GPO Spoofing and Execution Tampering</xhtml:strong>: An attacker positioned on the local network using man-in-the-middle (MitM) techniques (such as ARP spoofing or DNS poisoning) can intercept GPO retrieval traffic. Without Hardened UNC Paths, the attacker can spoof the Domain Controller and inject a malicious GPO or a modified script, which then executes with local SYSTEM privileges on the client host. Enforcing integrity and mutual authentication on <xhtml:code>SYSVOL</xhtml:code> and <xhtml:code>NETLOGON</xhtml:code> blocks this spoofing vector. 2. <xhtml:strong>Insecure Guest Logons</xhtml:strong>: Disabling insecure guest logons stops the workstation or server from automatically authenticating to untrusted remote SMB shares using guest credentials. This prevents attackers from setting up rogue SMB servers that trick hosts into leaking NetNTLM credentials or executing untrusted files. 3. <xhtml:strong>LDAP Session Hijacking</xhtml:strong>: Forcing outgoing LDAP client connections to negotiate signing protects directory queries made by Member Servers or Domain Controllers (acting as clients) from interception, packet tampering, or sniffing.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure Hardened UNC Paths</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to all target computers (e.g., <xhtml:code>GPO_Computer_Hardening_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Network Provider</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Hardened UNC Paths</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Show...</xhtml:strong> in the options panel, and add the following entries:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>
            <xhtml:em>: `\\</xhtml:em>\NETLOGON<xhtml:code> | **Value**: </xhtml:code>RequireIntegrity=1,RequireMutualAuthentication=1`</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>
            <xhtml:em>: `\\</xhtml:em>\SYSVOL<xhtml:code> | **Value**: </xhtml:code>RequireIntegrity=1,RequireMutualAuthentication=1`</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Disable Insecure Guest Logons</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Lanman Workstation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Enable insecure guest logons</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Disabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Enforce LDAP Client Signing</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Network security: LDAP client signing requirements</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Require signing</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to apply the hardened network provider, Lanman Workstation, and LDAP client configurations.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-HardenedUNCAndClientSigning.ps1">Download Script: Set-HardenedUNCAndClientSigning.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-HardenedUNCAndClientSigning.ps1
# Description: Configures Hardened UNC Paths for SYSVOL/NETLOGON, disables insecure guest logons, and enforces LDAP client signing.

Write-Host "Applying network provider and client channel hardening..." -ForegroundColor Cyan

# 1. Hardened UNC Paths configuration
$UNCPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths"
if (-not (Test-Path $UNCPath)) {
    New-Item -Path $UNCPath -Force | Out-Null
}
Set-ItemProperty -Path $UNCPath -Name "\\*\NETLOGON" -Value "RequireIntegrity=1,RequireMutualAuthentication=1" -Type String -ErrorAction Stop
Set-ItemProperty -Path $UNCPath -Name "\\*\SYSVOL" -Value "RequireIntegrity=1,RequireMutualAuthentication=1" -Type String -ErrorAction Stop
Write-Host "[+] Hardened UNC Paths for NETLOGON and SYSVOL configured." -ForegroundColor Green

# 2. Disable Insecure Guest Logons
$LanmanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation"
if (-not (Test-Path $LanmanPath)) {
    New-Item -Path $LanmanPath -Force | Out-Null
}
Set-ItemProperty -Path $LanmanPath -Name "AllowInsecureGuestAuth" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Insecure guest logons disabled." -ForegroundColor Green

# 3. Enforce LDAP Client Signing Requirements
$LdapPath = "HKLM:\System\CurrentControlSet\Services\LDAP"
if (-not (Test-Path $LdapPath)) {
    New-Item -Path $LdapPath -Force | Out-Null
}
Set-ItemProperty -Path $LdapPath -Name "ldapclientintegrity" -Value 2 -Type DWord -ErrorAction Stop
Write-Host "[+] LDAP Client signing requirement set to Require signing." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the network provider, Lanman workstation, and LDAP client signing configurations:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-HardenedUNCAndClientSigningStatus.ps1">Download Script: Get-HardenedUNCAndClientSigningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-HardenedUNCAndClientSigningStatus.ps1
# Description: Audits the registry configuration of Hardened UNC Paths, Lanman guest authentication, and LDAP Client signing.

Write-Host "--- Auditing Hardened UNC Paths and Client Signing status ---" -ForegroundColor Cyan

# 1. Audit UNC Paths
$UNCPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths"
if (Test-Path $UNCPath) {
    $NetlogonVal = Get-ItemProperty -Path $UNCPath -Name "\\*\NETLOGON" -ErrorAction SilentlyContinue
    $SysvolVal = Get-ItemProperty -Path $UNCPath -Name "\\*\SYSVOL" -ErrorAction SilentlyContinue
    
    $NetColor = if ($NetlogonVal -and $NetlogonVal.'\\*\NETLOGON' -eq "RequireIntegrity=1,RequireMutualAuthentication=1") { "Green" } else { "Red" }
    $SysColor = if ($SysvolVal -and $SysvolVal.'\\*\SYSVOL' -eq "RequireIntegrity=1,RequireMutualAuthentication=1") { "Green" } else { "Red" }
    
    Write-Host "    - Hardened UNC NETLOGON: $($NetlogonVal.'\\*\NETLOGON') (Expected: RequireIntegrity=1,RequireMutualAuthentication=1)" -ForegroundColor $NetColor
    Write-Host "    - Hardened UNC SYSVOL:   $($SysvolVal.'\\*\SYSVOL') (Expected: RequireIntegrity=1,RequireMutualAuthentication=1)" -ForegroundColor $SysColor
} else {
    Write-Host "    - Hardened UNC registry path: NOT FOUND" -ForegroundColor Red
}

# 2. Audit Guest Logons
$LanmanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation"
$GuestVal = Get-ItemProperty -Path $LanmanPath -Name "AllowInsecureGuestAuth" -ErrorAction SilentlyContinue
$GuestSetting = if ($GuestVal) { $GuestVal.AllowInsecureGuestAuth } else { 1 }
$GuestColor = if ($GuestSetting -eq 0) { "Green" } else { "Red" }
Write-Host "    - Allow Insecure Guest Logons: $GuestSetting (Expected: 0)" -ForegroundColor $GuestColor

# 3. Audit LDAP Client Signing
$LdapPath = "HKLM:\System\CurrentControlSet\Services\LDAP"
$LdapVal = Get-ItemProperty -Path $LdapPath -Name "ldapclientintegrity" -ErrorAction SilentlyContinue
$LdapSetting = if ($LdapVal) { $LdapVal.ldapclientintegrity } else { 0 }
$LdapColor = if ($LdapSetting -eq 2) { "Green" } else { "Red" }
Write-Host "    - LDAP Client Integrity (Signing): $LdapSetting (Expected: 2 - Require)" -ForegroundColor $LdapColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-HardenedUNCAndClientSigning.ps1
# Description: Configures Hardened UNC Paths for SYSVOL/NETLOGON, disables insecure guest logons, and enforces LDAP client signing.

Write-Host "Applying network provider and client channel hardening..." -ForegroundColor Cyan

# 1. Hardened UNC Paths configuration
$UNCPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths"
if (-not (Test-Path $UNCPath)) {
    New-Item -Path $UNCPath -Force | Out-Null
}
Set-ItemProperty -Path $UNCPath -Name "\\*\NETLOGON" -Value "RequireIntegrity=1,RequireMutualAuthentication=1" -Type String -ErrorAction Stop
Set-ItemProperty -Path $UNCPath -Name "\\*\SYSVOL" -Value "RequireIntegrity=1,RequireMutualAuthentication=1" -Type String -ErrorAction Stop
Write-Host "[+] Hardened UNC Paths for NETLOGON and SYSVOL configured." -ForegroundColor Green

# 2. Disable Insecure Guest Logons
$LanmanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation"
if (-not (Test-Path $LanmanPath)) {
    New-Item -Path $LanmanPath -Force | Out-Null
}
Set-ItemProperty -Path $LanmanPath -Name "AllowInsecureGuestAuth" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Insecure guest logons disabled." -ForegroundColor Green

# 3. Enforce LDAP Client Signing Requirements
$LdapPath = "HKLM:\System\CurrentControlSet\Services\LDAP"
if (-not (Test-Path $LdapPath)) {
    New-Item -Path $LdapPath -Force | Out-Null
}
Set-ItemProperty -Path $LdapPath -Name "ldapclientintegrity" -Value 2 -Type DWord -ErrorAction Stop
Write-Host "[+] LDAP Client signing requirement set to Require signing." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4009" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-010" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-010] Harden WinRM Service and Restrict Remote RPC Clients</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Clients.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/harden-winrm-service.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Remote Management (WinRM) and Remote Procedure Call (RPC) are standard management interfaces in Windows environments. However, by default, these interfaces allow backward-compatible configurations that pose significant security risks.</xhtml:p>
        <xhtml:p>Hardening these service channels blocks the following exploit vectors: 1. <xhtml:strong>Plaintext Credential Harvesting</xhtml:strong>: Allowing Basic authentication on WinRM clients and services allows transmission of administrative passwords in plaintext (or easily decodable formats) if secure channels are not established. Disabling Basic and Digest authentication forces the use of Kerberos or certificate-based authentication. 2. <xhtml:strong>Replay and Eavesdropping</xhtml:strong>: WinRM allows unencrypted traffic by default, which exposes administrative payloads and remote command execution streams to sniffing and hijacking. Forcing encryption protects the confidentiality and integrity of remote management sessions. 3. <xhtml:strong>RunAs Credential Exposure</xhtml:strong>: If WinRM is allowed to cache or store RunAs credentials for remote task execution, those credentials reside in the host's memory, where an administrative attacker can harvest them using memory extraction tools. 4. <xhtml:strong>Anonymous RPC Enumeration</xhtml:strong>: Restricting unauthenticated RPC clients prevents anonymous attackers from performing remote enumeration of active services, RPC interfaces, and registry endpoints, limiting remote reconnaissance capabilities.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure WinRM Client Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting all computers (e.g., <xhtml:code>GPO_Computer_Hardening_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM Client</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow Basic authentication` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow unencrypted traffic` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Disallow Digest authentication` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure WinRM Service Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM Service</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow Basic authentication` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow unencrypted traffic` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Disallow WinRM from storing RunAs credentials` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Configure Windows Remote Shell Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Remote Shell</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow Remote Shell Access` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Configure RPC Client Restrictions</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Remote Procedure Call</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Restrict Unauthenticated RPC clients</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the options dropdown, select <xhtml:strong>Authenticated</xhtml:strong> (corresponds to registry value <xhtml:code>1</xhtml:code>).</xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enforce WinRM client/service and RPC restrictions in the registry.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-WinRMAndRpcHardening.ps1">Download Script: Set-WinRMAndRpcHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-WinRMAndRpcHardening.ps1
# Description: Hardens WinRM client/service parameters and restricts remote RPC clients.

Write-Host "Applying WinRM and RPC channel hardening settings..." -ForegroundColor Cyan

# 1. WinRM Client Hardening
$ClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client"
if (-not (Test-Path $ClientPath)) {
    New-Item -Path $ClientPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientPath -Name "AllowBasic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ClientPath -Name "AllowUnencryptedTraffic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ClientPath -Name "AllowDigest" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] WinRM Client parameters hardened." -ForegroundColor Green

# 2. WinRM Service Hardening
$ServicePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service"
if (-not (Test-Path $ServicePath)) {
    New-Item -Path $ServicePath -Force | Out-Null
}
Set-ItemProperty -Path $ServicePath -Name "AllowBasic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ServicePath -Name "AllowUnencryptedTraffic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ServicePath -Name "DisableRunAs" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] WinRM Service parameters hardened." -ForegroundColor Green

# 3. Windows Remote Shell Hardening
$WinRsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS"
if (-not (Test-Path $WinRsPath)) {
    New-Item -Path $WinRsPath -Force | Out-Null
}
Set-ItemProperty -Path $WinRsPath -Name "AllowRemoteShellAccess" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Windows Remote Shell access disabled." -ForegroundColor Green

# 4. RPC Client Restrictions
$RpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc"
if (-not (Test-Path $RpcPath)) {
    New-Item -Path $RpcPath -Force | Out-Null
}
Set-ItemProperty -Path $RpcPath -Name "RestrictRemoteClients" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Unauthenticated RPC client restrictions enforced (RestrictRemoteClients = 1)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the WinRM client/service and RPC client settings status:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-WinRMAndRpcHardeningStatus.ps1">Download Script: Get-WinRMAndRpcHardeningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WinRMAndRpcHardeningStatus.ps1
# Description: Audits registry configuration of WinRM client/service options and RPC client restrictions.

Write-Host "--- Auditing WinRM and RPC Hardening Settings ---" -ForegroundColor Cyan

# 1. Audit WinRM Client
$ClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client"
$ExpectedClient = @{
    "AllowBasic"              = 0
    "AllowUnencryptedTraffic" = 0
    "AllowDigest"             = 0
}
if (Test-Path $ClientPath) {
    $ClientReg = Get-ItemProperty -Path $ClientPath -ErrorAction SilentlyContinue
    foreach ($S in $ExpectedClient.Keys) {
        $Val = $ClientReg.$S
        $Expected = $ExpectedClient[$S]
        $Color = if ($Val -eq $Expected) { "Green" } else { "Red" }
        Write-Host "    - WinRM Client $($S): $Val (Expected: $Expected)" -ForegroundColor $Color
    }
} else {
    Write-Host "    - WinRM Client Registry: NOT FOUND" -ForegroundColor Red
}

# 2. Audit WinRM Service
$ServicePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service"
$ExpectedService = @{
    "AllowBasic"              = 0
    "AllowUnencryptedTraffic" = 0
    "DisableRunAs"            = 1
}
if (Test-Path $ServicePath) {
    $ServiceReg = Get-ItemProperty -Path $ServicePath -ErrorAction SilentlyContinue
    foreach ($S in $ExpectedService.Keys) {
        $Val = $ServiceReg.$S
        $Expected = $ExpectedService[$S]
        $Color = if ($Val -eq $Expected) { "Green" } else { "Red" }
        Write-Host "    - WinRM Service $($S): $Val (Expected: $Expected)" -ForegroundColor $Color
    }
} else {
    Write-Host "    - WinRM Service Registry: NOT FOUND" -ForegroundColor Red
}

# 3. Audit Windows Remote Shell
$WinRsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS"
if (Test-Path $WinRsPath) {
    $WinRsReg = Get-ItemProperty -Path $WinRsPath -ErrorAction SilentlyContinue
    $RsVal = $WinRsReg.AllowRemoteShellAccess
    $RsColor = if ($RsVal -eq 0) { "Green" } else { "Red" }
    Write-Host "    - Windows Remote Shell AllowRemoteShellAccess: $RsVal (Expected: 0)" -ForegroundColor $RsColor
} else {
    Write-Host "    - Windows Remote Shell Registry: NOT FOUND" -ForegroundColor Red
}

# 4. Audit RPC Clients
$RpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc"
$RpcVal = Get-ItemProperty -Path $RpcPath -Name "RestrictRemoteClients" -ErrorAction SilentlyContinue
$RpcSetting = if ($RpcVal) { $RpcVal.RestrictRemoteClients } else { 0 }
$RpcColor = if ($RpcSetting -eq 1) { "Green" } else { "Red" }
Write-Host "    - RPC RestrictRemoteClients: $RpcSetting (Expected: 1)" -ForegroundColor $RpcColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-WinRMAndRpcHardening.ps1
# Description: Hardens WinRM client/service parameters and restricts remote RPC clients.

Write-Host "Applying WinRM and RPC channel hardening settings..." -ForegroundColor Cyan

# 1. WinRM Client Hardening
$ClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client"
if (-not (Test-Path $ClientPath)) {
    New-Item -Path $ClientPath -Force | Out-Null
}
Set-ItemProperty -Path $ClientPath -Name "AllowBasic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ClientPath -Name "AllowUnencryptedTraffic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ClientPath -Name "AllowDigest" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] WinRM Client parameters hardened." -ForegroundColor Green

# 2. WinRM Service Hardening
$ServicePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service"
if (-not (Test-Path $ServicePath)) {
    New-Item -Path $ServicePath -Force | Out-Null
}
Set-ItemProperty -Path $ServicePath -Name "AllowBasic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ServicePath -Name "AllowUnencryptedTraffic" -Value 0 -Type DWord -ErrorAction Stop
Set-ItemProperty -Path $ServicePath -Name "DisableRunAs" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] WinRM Service parameters hardened." -ForegroundColor Green

# 3. Windows Remote Shell Hardening
$WinRsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS"
if (-not (Test-Path $WinRsPath)) {
    New-Item -Path $WinRsPath -Force | Out-Null
}
Set-ItemProperty -Path $WinRsPath -Name "AllowRemoteShellAccess" -Value 0 -Type DWord -ErrorAction Stop
Write-Host "[+] Windows Remote Shell access disabled." -ForegroundColor Green

# 4. RPC Client Restrictions
$RpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc"
if (-not (Test-Path $RpcPath)) {
    New-Item -Path $RpcPath -Force | Out-Null
}
Set-ItemProperty -Path $RpcPath -Name "RestrictRemoteClients" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Unauthenticated RPC client restrictions enforced (RestrictRemoteClients = 1)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-011" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-011] Configure WMI Static Port and Service Hardening</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>&gt; [!NOTE] &gt; Client workstations and Privileged Access Workstations (PAWs) must not expose remote WMI endpoints. Inbound remote management protocols on endpoints are blocked entirely by workstation isolation controls (<xhtml:strong>[REQ-NET-003]</xhtml:strong>) and Defender Attack Surface Reduction (ASR) rules (<xhtml:strong>[REQ-PAW-088]</xhtml:strong> and <xhtml:strong>[REQ-END-092]</xhtml:strong>).</xhtml:p>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-wmi-static-port.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Management Instrumentation (WMI) is a core Windows administration framework built upon the Distributed Component Object Model (DCOM) and Remote Procedure Call (RPC) protocols. By default, WMI runs inside a shared service host process (<xhtml:code>svchost.exe -k netsvcs</xhtml:code>) and dynamically allocates ephemeral high-order TCP ports (range <xhtml:code>49152-65535</xhtml:code>) for remote client connections.</xhtml:p>
        <xhtml:p>Leaving WMI in its default configuration presents four critical security risks:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>The Dynamic RPC Port Dilemma &amp; Attack Surface Exposure</xhtml:strong>:</xhtml:li>
          <xhtml:li>Because remote WMI clients dynamically negotiate communication ports via the RPC Endpoint Mapper (RPCSS on TCP port 135), network administrators who allow remote WMI must either open the entire ephemeral dynamic port range (<xhtml:code>49152-65535</xhtml:code>) on network firewalls or disable host firewalls entirely. Opening thousands of dynamic ports circumvents perimeter filtering and exposes every local service listening on high-order sockets to unauthorized network traversal. Pinning WMI to a dedicated static port (TCP <xhtml:code>24158</xhtml:code>) allows network and host firewalls to block the broad dynamic range and enforce strict microsegmentation.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Lateral Movement and Living-off-the-Land Exploitation (MITRE ATT&amp;CK T1047)</xhtml:strong>:</xhtml:li>
          <xhtml:li>Adversaries frequently leverage WMI to orchestrate stealthy lateral movement, execute remote code, query system configuration, and deploy backdoors without triggering interactive logon events (Event ID 4624 Type 3 network logons). Widely abused post-exploitation toolkits (such as Impacket's <xhtml:code>wmiexec.py</xhtml:code>, SharpWMI, and PowerShell CIM cmdlets) abuse DCOM interfaces to spawn malicious processes under <xhtml:code>WmiPrvSE.exe</xhtml:code> (e.g., <xhtml:code>Win32_Process.Create</xhtml:code>). Restricting WMI to static port 24158 and strictly scoping firewall access to authorized PAW subnets eliminates unmonitored cross-subnet living-off-the-land attacks.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Wire Eavesdropping and Session Tampering Mitigation (CVE-2021-26414)</xhtml:strong>:</xhtml:li>
          <xhtml:li>Remote DCOM communications that operate below authentication level 6 (<xhtml:code>RPC_C_AUTHN_LEVEL_PKT_PRIVACY</xhtml:code>) do not encrypt payload data. Attackers positioned on the network path could intercept sensitive administrative data returned in WMI queries (such as system configurations, installed software inventories, environment variables, or process lists) or tamper with in-flight RPC commands. Enforcing <xhtml:code>AuthenticationLevel = 6</xhtml:code> mandates packet-level Kerberos or NTLM encryption across all WMI communications, fully satisfying Microsoft DCOM security hardening requirements (KB5004442).</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Process Isolation and Memory Containment</xhtml:strong>:</xhtml:li>
          <xhtml:li>By default, the <xhtml:code>winmgmt</xhtml:code> service shares a single <xhtml:code>svchost.exe</xhtml:code> process instance with multiple other system services (such as IP Helper, Background Intelligent Transfer Service, and Windows Update). Moving WMI into a standalone host process (<xhtml:code>SERVICE_WIN32_OWN_PROCESS</xhtml:code>, <xhtml:code>Type = 16</xhtml:code>) isolates its heap, thread pools, security tokens, and memory space. If an adjacent service running in a shared host process is compromised, process isolation prevents direct in-memory manipulation, token stealing, or tampering with directory management capabilities.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Define Static WMI Port, Packet Privacy, and Service Type via GPO Registry Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting the target systems (e.g., <xhtml:code>GPO_Hardening_Firewall_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Define the following <xhtml:strong>Registry Items</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>WMI Static Port Assignment</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Classes\AppID\{8BC3F05E-D86B-11D0-A075-00C04FB68820}</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Endpoints</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_MULTI_SZ</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>ncacn_ip_tcp,0,24158</xhtml:code> (Enter on a single line)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>WMI DCOM Packet Privacy Authentication Level</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Classes\AppID\{8BC3F05E-D86B-11D0-A075-00C04FB68820}</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AuthenticationLevel</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>6</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>WMI Standalone Process Type</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Services\winmgmt</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Type</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>16</xhtml:code> (Decimal)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Windows Defender Firewall with Advanced Security</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same or linked GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security - [LDAP Path]\Inbound Rules</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new custom Inbound Rule:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Port</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Protocol and Ports</xhtml:em>*: <xhtml:code>TCP</xhtml:code>, Specific local ports: <xhtml:code>24158</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Allow the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: Check <xhtml:code>Domain</xhtml:code> and <xhtml:code>Private</xhtml:code> (uncheck <xhtml:code>Public</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>AD-Hardening-WMI-StaticPort-In</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Description</xhtml:em>*: <xhtml:code>Permits inbound WMI traffic on dedicated static TCP port 24158 from authorized Tier 1 / PAW management subnets.</xhtml:code>
          </xhtml:li>
          <xhtml:li>Open the properties of <xhtml:code>AD-Hardening-WMI-StaticPort-In</xhtml:code> and navigate to the <xhtml:strong>Scope</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Under </xhtml:em>
            <xhtml:em>Remote IP address</xhtml:em>
            <xhtml:em>, select </xhtml:em>
            <xhtml:em>These IP addresses</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Add the specific IP subnets of authorized PAWs, Tier 1 management bastions, and centralized SIEM/monitoring collectors. Do </xhtml:em>
            <xhtml:em>not</xhtml:em>
            <xhtml:em> leave this set to </xhtml:em>Any IP address*.</xhtml:li>
          <xhtml:li>Verify or create an inbound rule for the <xhtml:strong>RPC Endpoint Mapper</xhtml:strong>:</xhtml:li>
          <xhtml:li>* Protocol: <xhtml:code>TCP</xhtml:code>, Port: <xhtml:code>135</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Scope: Restrict remote IP addresses strictly to the same authorized management subnets.</xhtml:li>
          <xhtml:li>Disable generic dynamic WMI rules:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure the predefined rule group `Windows Management Instrumentation (WMI)` is </xhtml:em>
            <xhtml:em>not</xhtml:em>* enabled broadly, or set explicit block rules for dynamic high ports <xhtml:code>49152-65535</xhtml:code> from non-management subnets.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Host Maintenance Reboot</xhtml:h4>
        <xhtml:p>Deploy the GPO to the target Organizational Unit (OU) and plan a host reboot during the next maintenance window to initialize the standalone host process cleanly.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to apply the WMI static port configuration and host firewall restrictions.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-WMIStaticPort.ps1">Download Script: Set-WMIStaticPort.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-WMIStaticPort.ps1
# Description: Configures WMI to run in a standalone host process on static TCP port 24158 with packet privacy and configures host firewall rules.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [string[]]$ManagementSubnets = @()
)

Write-Host "Applying hardening requirement: Configure WMI Static Port and Service Hardening..." -ForegroundColor Cyan

# 1. Configure the static TCP port 24158 for WMI AppID
$WmiAppIdPath = "HKLM:\SOFTWARE\Classes\AppID\{8BC3F05E-D86B-11D0-A075-00C04FB68820}"
if (-not (Test-Path -Path $WmiAppIdPath)) {
    New-Item -Path $WmiAppIdPath -Force | Out-Null
}

Set-ItemProperty -Path $WmiAppIdPath -Name "Endpoints" -Value @("ncacn_ip_tcp,0,24158") -Type MultiString
Write-Host "[+] Configured WMI AppID static endpoint to TCP 24158." -ForegroundColor Green

# 2. Configure DCOM Authentication Level to Packet Privacy (6)
Set-ItemProperty -Path $WmiAppIdPath -Name "AuthenticationLevel" -Value 6 -Type DWord
Write-Host "[+] Configured WMI AppID DCOM authentication level to 6 (RPC_C_AUTHN_LEVEL_PKT_PRIVACY)." -ForegroundColor Green

# 3. Configure WMI service execution type to Standalone Host (Type = 16 / SERVICE_WIN32_OWN_PROCESS)
$WinmgmtSvcPath = "HKLM:\SYSTEM\CurrentControlSet\Services\winmgmt"
if (-not (Test-Path -Path $WinmgmtSvcPath)) {
    New-Item -Path $WinmgmtSvcPath -Force | Out-Null
}
Set-ItemProperty -Path $WinmgmtSvcPath -Name "Type" -Value 16 -Type DWord
Write-Host "[+] Configured WMI service execution type to 16 (SERVICE_WIN32_OWN_PROCESS)." -ForegroundColor Green

# 4. Invoke winmgmt standalone host configuration command
Write-Host "[+] Executing winmgmt.exe /standalonehost 6..." -ForegroundColor Gray
$Proc = Start-Process -FilePath "winmgmt.exe" -ArgumentList "/standalonehost 6" -Wait -NoNewWindow -PassThru

if ($Proc.ExitCode -eq 0) {
    Write-Host "[+] WMI standalone host command completed successfully." -ForegroundColor Green
} else {
    Write-Warning "[-] WMI standalone host command exited with code $($Proc.ExitCode)."
}

# 5. Configure Windows Defender Firewall Inbound Rule for WMI Static Port 24158
Write-Host "[+] Configuring Windows Defender Firewall rule for static TCP port 24158..." -ForegroundColor Gray
$RuleName = "AD-Hardening-WMI-StaticPort-In"
$ExistingRule = Get-NetFirewallRule -Name $RuleName -ErrorAction SilentlyContinue

$FirewallParams = @{
    DisplayName = "Active Directory Hardening - WMI Static Port (TCP 24158)"
    Description = "Permits inbound DCOM/WMI traffic on dedicated static TCP port 24158 from authorized management hosts."
    Direction   = "Inbound"
    Action      = "Allow"
    Protocol    = "TCP"
    LocalPort   = "24158"
    Profile     = "Domain,Private"
    Enabled     = "True"
}

if ($ManagementSubnets.Count -gt 0) {
    $FirewallParams["RemoteAddress"] = $ManagementSubnets
}

if ($ExistingRule) {
    Set-NetFirewallRule -Name $RuleName @FirewallParams | Out-Null
    Write-Host "[+] Updated existing firewall rule: $RuleName." -ForegroundColor Green
} else {
    New-NetFirewallRule -Name $RuleName @FirewallParams | Out-Null
    Write-Host "[+] Created new inbound firewall rule: $RuleName." -ForegroundColor Green
}

# 6. Disable unconstrained dynamic WMI inbound rules to prevent ephemeral port exposure
Write-Host "[+] Disabling built-in dynamic WMI firewall rules..." -ForegroundColor Gray
$DynamicWmiRules = Get-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)" -ErrorAction SilentlyContinue |
    Where-Object { $_.Direction -eq "Inbound" -and $_.Name -like "*WMI-In*" -and $_.Name -ne $RuleName }

foreach ($DynRule in $DynamicWmiRules) {
    Disable-NetFirewallRule -Name $DynRule.Name | Out-Null
    Write-Host "    - Disabled dynamic WMI rule: $($DynRule.DisplayName)" -ForegroundColor Gray
}

Write-Host "`n[+] Hardening configuration applied successfully." -ForegroundColor Cyan
Write-Host "[!] IMPORTANT: A system reboot is strongly recommended to cleanly apply WMI service isolation and restart all dependent infrastructure services." -ForegroundColor Yellow</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-WMIStaticPort.ps1">Download Script: Test-WMIStaticPort.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-WMIStaticPort.ps1
# Description: Audits WMI static port registry configuration, DCOM authentication level, service isolation, and firewall rules.
# Target Engine: Windows PowerShell 5.1

Write-Host "Auditing WMI static port configuration and service hardening..." -ForegroundColor Cyan
$vulnerable = $false

# 1. Audit AppID Endpoints Registry Setting
$WmiAppIdPath = "HKLM:\SOFTWARE\Classes\AppID\{8BC3F05E-D86B-11D0-A075-00C04FB68820}"
$AppIdProps = Get-ItemProperty -Path $WmiAppIdPath -ErrorAction SilentlyContinue

if ($AppIdProps -and $AppIdProps.Endpoints) {
    $Endpoints = $AppIdProps.Endpoints
    if ($Endpoints -contains "ncacn_ip_tcp,0,24158") {
        Write-Host "[+] WMI static port registry endpoint is configured correctly (TCP 24158)." -ForegroundColor Green
    } else {
        Write-Host "[!] NON-COMPLIANT: WMI Endpoints registry value is: '$($Endpoints -join ', ')' (Expected: 'ncacn_ip_tcp,0,24158')" -ForegroundColor Red
        $vulnerable = $true
    }
} else {
    Write-Host "[!] NON-COMPLIANT: WMI AppID 'Endpoints' registry value is missing or inaccessible." -ForegroundColor Red
    $vulnerable = $true
}

# 2. Audit AppID DCOM Authentication Level (Packet Privacy = 6)
if ($AppIdProps -and $null -ne $AppIdProps.AuthenticationLevel) {
    $AuthLevel = [int]$AppIdProps.AuthenticationLevel
    if ($AuthLevel -ge 6) {
        Write-Host "[+] WMI AppID DCOM AuthenticationLevel is configured to Packet Privacy ($AuthLevel)." -ForegroundColor Green
    } else {
        Write-Host "[!] NON-COMPLIANT: WMI AppID AuthenticationLevel is: $AuthLevel (Expected: 6 [RPC_C_AUTHN_LEVEL_PKT_PRIVACY])" -ForegroundColor Red
        $vulnerable = $true
    }
} else {
    Write-Host "[!] NON-COMPLIANT: WMI AppID 'AuthenticationLevel' value is missing (Expected: 6)." -ForegroundColor Red
    $vulnerable = $true
}

# 3. Audit WMI Service Execution Type (Standalone Host = 16)
$WinmgmtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\winmgmt"
$TypeVal = Get-ItemProperty -Path $WinmgmtPath -Name "Type" -ErrorAction SilentlyContinue

if ($TypeVal -and $null -ne $TypeVal.Type) {
    $Type = [int]$TypeVal.Type
    if ($Type -eq 16) {
        Write-Host "[+] WMI is configured to run as a standalone process (Type = 16 [SERVICE_WIN32_OWN_PROCESS])." -ForegroundColor Green
    } else {
        Write-Host "[!] NON-COMPLIANT: WMI service execution type is: $Type (Expected: 16 [SERVICE_WIN32_OWN_PROCESS])" -ForegroundColor Red
        $vulnerable = $true
    }
} else {
    Write-Host "[!] NON-COMPLIANT: WMI service registry key is missing or inaccessible." -ForegroundColor Red
    $vulnerable = $true
}

# 4. Audit Host Firewall Inbound Rule for TCP 24158
$FwRules = Get-NetFirewallRule -Direction Inbound -Enabled True -ErrorAction SilentlyContinue |
    Where-Object { $_.Action -eq "Allow" }

$WmiStaticPortAllowed = $false
foreach ($Rule in $FwRules) {
    $PortFilter = Get-NetFirewallPortFilter -AssociatedNetFirewallRule $Rule -ErrorAction SilentlyContinue
    if ($PortFilter -and $PortFilter.Protocol -eq "TCP") {
        $LocalPorts = @($PortFilter.LocalPort)
        if ($LocalPorts -contains "24158") {
            $WmiStaticPortAllowed = $true
            break
        }
    }
}

if ($WmiStaticPortAllowed) {
    Write-Host "[+] Windows Defender Firewall has an active inbound allow rule for TCP port 24158." -ForegroundColor Green
} else {
    Write-Host "[!] NON-COMPLIANT: No active inbound firewall rule permitting TCP port 24158 found." -ForegroundColor Red
    $vulnerable = $true
}

# 5. Audit Built-in Dynamic WMI Firewall Rules
$DynamicWmiRules = Get-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)" -Direction Inbound -Enabled True -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -like "*WMI-In*" }

if ($DynamicWmiRules) {
    $UnrestrictedDynamicRule = $false
    foreach ($DynRule in $DynamicWmiRules) {
        $AddressFilter = Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $DynRule -ErrorAction SilentlyContinue
        if ($AddressFilter -and ($AddressFilter.RemoteAddress -contains "Any" -or -not $AddressFilter.RemoteAddress)) {
            $UnrestrictedDynamicRule = $true
            break
        }
    }
    if ($UnrestrictedDynamicRule) {
        Write-Host "[!] NON-COMPLIANT: Built-in dynamic WMI firewall rules are enabled and allow unconstrained dynamic RPC ports from Any address." -ForegroundColor Red
        $vulnerable = $true
    } else {
        Write-Host "[+] Built-in dynamic WMI firewall rules are restricted to specific subnets." -ForegroundColor Green
    }
} else {
    Write-Host "[+] Built-in generic dynamic WMI inbound firewall rules are disabled." -ForegroundColor Green
}

# Final Verdict
if ($vulnerable) {
    Write-Host "Audit result: NON-COMPLIANT" -ForegroundColor Red
} else {
    Write-Host "Audit result: COMPLIANT" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-WMIStaticPort.ps1
# Description: Configures WMI to run in a standalone host process on static TCP port 24158 with packet privacy and configures host firewall rules.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [string[]]$ManagementSubnets = @()
)

Write-Host "Applying hardening requirement: Configure WMI Static Port and Service Hardening..." -ForegroundColor Cyan

# 1. Configure the static TCP port 24158 for WMI AppID
$WmiAppIdPath = "HKLM:\SOFTWARE\Classes\AppID\{8BC3F05E-D86B-11D0-A075-00C04FB68820}"
if (-not (Test-Path -Path $WmiAppIdPath)) {
    New-Item -Path $WmiAppIdPath -Force | Out-Null
}

Set-ItemProperty -Path $WmiAppIdPath -Name "Endpoints" -Value @("ncacn_ip_tcp,0,24158") -Type MultiString
Write-Host "[+] Configured WMI AppID static endpoint to TCP 24158." -ForegroundColor Green

# 2. Configure DCOM Authentication Level to Packet Privacy (6)
Set-ItemProperty -Path $WmiAppIdPath -Name "AuthenticationLevel" -Value 6 -Type DWord
Write-Host "[+] Configured WMI AppID DCOM authentication level to 6 (RPC_C_AUTHN_LEVEL_PKT_PRIVACY)." -ForegroundColor Green

# 3. Configure WMI service execution type to Standalone Host (Type = 16 / SERVICE_WIN32_OWN_PROCESS)
$WinmgmtSvcPath = "HKLM:\SYSTEM\CurrentControlSet\Services\winmgmt"
if (-not (Test-Path -Path $WinmgmtSvcPath)) {
    New-Item -Path $WinmgmtSvcPath -Force | Out-Null
}
Set-ItemProperty -Path $WinmgmtSvcPath -Name "Type" -Value 16 -Type DWord
Write-Host "[+] Configured WMI service execution type to 16 (SERVICE_WIN32_OWN_PROCESS)." -ForegroundColor Green

# 4. Invoke winmgmt standalone host configuration command
Write-Host "[+] Executing winmgmt.exe /standalonehost 6..." -ForegroundColor Gray
$Proc = Start-Process -FilePath "winmgmt.exe" -ArgumentList "/standalonehost 6" -Wait -NoNewWindow -PassThru

if ($Proc.ExitCode -eq 0) {
    Write-Host "[+] WMI standalone host command completed successfully." -ForegroundColor Green
} else {
    Write-Warning "[-] WMI standalone host command exited with code $($Proc.ExitCode)."
}

# 5. Configure Windows Defender Firewall Inbound Rule for WMI Static Port 24158
Write-Host "[+] Configuring Windows Defender Firewall rule for static TCP port 24158..." -ForegroundColor Gray
$RuleName = "AD-Hardening-WMI-StaticPort-In"
$ExistingRule = Get-NetFirewallRule -Name $RuleName -ErrorAction SilentlyContinue

$FirewallParams = @{
    DisplayName = "Active Directory Hardening - WMI Static Port (TCP 24158)"
    Description = "Permits inbound DCOM/WMI traffic on dedicated static TCP port 24158 from authorized management hosts."
    Direction   = "Inbound"
    Action      = "Allow"
    Protocol    = "TCP"
    LocalPort   = "24158"
    Profile     = "Domain,Private"
    Enabled     = "True"
}

if ($ManagementSubnets.Count -gt 0) {
    $FirewallParams["RemoteAddress"] = $ManagementSubnets
}

if ($ExistingRule) {
    Set-NetFirewallRule -Name $RuleName @FirewallParams | Out-Null
    Write-Host "[+] Updated existing firewall rule: $RuleName." -ForegroundColor Green
} else {
    New-NetFirewallRule -Name $RuleName @FirewallParams | Out-Null
    Write-Host "[+] Created new inbound firewall rule: $RuleName." -ForegroundColor Green
}

# 6. Disable unconstrained dynamic WMI inbound rules to prevent ephemeral port exposure
Write-Host "[+] Disabling built-in dynamic WMI firewall rules..." -ForegroundColor Gray
$DynamicWmiRules = Get-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)" -ErrorAction SilentlyContinue |
    Where-Object { $_.Direction -eq "Inbound" -and $_.Name -like "*WMI-In*" -and $_.Name -ne $RuleName }

foreach ($DynRule in $DynamicWmiRules) {
    Disable-NetFirewallRule -Name $DynRule.Name | Out-Null
    Write-Host "    - Disabled dynamic WMI rule: $($DynRule.DisplayName)" -ForegroundColor Gray
}

Write-Host "`n[+] Hardening configuration applied successfully." -ForegroundColor Cyan
Write-Host "[!] IMPORTANT: A system reboot is strongly recommended to cleanly apply WMI service isolation and restart all dependent infrastructure services." -ForegroundColor Yellow</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-012" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-012] Configure RPC Filters for Named Pipes</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/configure-rpc-named-pipe-filters.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory domains heavily rely on the Server Message Block (SMB) protocol (TCP 445) for distributing group policies and replication via the SYSVOL and NETLOGON file shares. Because every joined domain member requires access to these shares, TCP port 445 cannot simply be blocked at the network perimeter or host firewall level on Domain Controllers.</xhtml:p>
        <xhtml:p>However, adversaries and post-exploitation frameworks (such as Impacket PsExec, SMBExec, AExec, Coercer, PetitPotam, and Mimikatz) routinely abuse this open SMB surface. Windows Remote Procedure Call (RPC) supports two primary transport protocols: 1. <xhtml:strong>RPC over TCP/IP (`ncacn_ip_tcp`)</xhtml:strong>: Binds each service dynamically (or to configured static ports) across ephemeral TCP ports (49152-65535). 2. <xhtml:strong>RPC over Named Pipes (`ncacn_np`)</xhtml:strong>: Multiplexes RPC requests directly through SMB named pipes over TCP port 445.</xhtml:p>
        <xhtml:p>Standard Layer 3 and Layer 4 firewall rules can only permit or block the entire TCP port 445. If TCP 445 is permitted, an attacker with network access can connect to sensitive SMB named pipes (such as <xhtml:code>\PIPE\svcctl</xhtml:code> or <xhtml:code>\PIPE\atsvc</xhtml:code>) to execute remote code or trigger authentication coercion without ever needing access to dynamic RPC ports.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Create the RPC Filters Definition File</xhtml:h4>
        <xhtml:p>Create a text file named <xhtml:code>RpcNamedPipesFilters.txt</xhtml:code> containing the following Netsh commands:</xhtml:p>
        <xhtml:pre>
          <xhtml:code>rpc filter

# [MS-SCMR] Block Service Control Manager over SMB named pipes (\PIPE\svcctl)
add rule layer=um actiontype=block filterkey=d0c7640c-9355-4e52-8335-c12835559c10
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=367ABB81-9844-35F1-AD32-98F038001003
add filter

# [MS-TSCH] Block Task Scheduler Remoting over SMB named pipes (\PIPE\atsvc)
add rule layer=um actiontype=block filterkey=a43b9dd2-0866-4476-89dc-2e9b200762af
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=86D35949-83C9-4044-B424-DB363231FD0C
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 1 (All transports)
add rule layer=um actiontype=block filterkey=13518c11-e3d8-4f62-9461-eda11beb540a
add condition field=if_uuid matchtype=equal data=1FF70682-0A51-30E8-076D-740BE8CEE98B
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 2 (All transports)
add rule layer=um actiontype=block filterkey=1c079a18-e91f-4698-9868-68a121490636
add condition field=if_uuid matchtype=equal data=378E52B0-C0A9-11CF-822D-00AA0051E40F
add filter

# [MS-EVEN6] Block EventLog v6.0 Remoting over SMB named pipes (\PIPE\eventlog)
add rule layer=um actiontype=block filterkey=dedffabf-db89-4177-be77-1954aa2c0b95
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=f6beaff7-1e19-4fbb-9f8f-b89e2018337c
add filter

# [MS-EVEN] Block Legacy EventLog Remoting Protocol (All transports)
add rule layer=um actiontype=block filterkey=f7f68868-5f50-4cda-a18c-6a7a549652e7
add condition field=if_uuid matchtype=equal data=82273FDC-E32A-18C3-3F78-827929DC23EA
add filter

# [MS-DFSNM] Permit DFS Namespace Management exclusively for Domain Admins (\PIPE\netdfs)
add rule layer=um actiontype=permit filterkey=43873c58-e130-4ffb-8858-d259a673a917
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add condition field=remote_user_token matchtype=equal data=D:(A;;CC;;;DA)
add filter

# [MS-DFSNM] Block DFS Namespace Management for all other users
add rule layer=um actiontype=block filterkey=0a239867-73db-45e6-b287-d006fe3c8b18
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add filter

# [MS-RPRN] Block Print System Remote Protocol over SMB named pipes (\PIPE\spoolss)
add rule layer=um actiontype=block filterkey=7966512a-f2f4-4cb1-812d-d967ab83d28a
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=12345678-1234-ABCD-EF00-0123456789AB
add filter

# [MS-EFSR] Permit EFSRPC via lsarpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=d71d00db-3eef-4935-bedf-20cf628abd9e
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via lsarpc
add rule layer=um actiontype=block filterkey=3a4cce27-a7fa-4248-b8b8-ef6439a2c0ff
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add filter

# [MS-EFSR] Permit EFSRPC via efsrpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=c5cf8020-c83c-4803-9241-8c7f3b10171f
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via efsrpc
add rule layer=um actiontype=block filterkey=9ad23a91-085d-4f99-ae15-85e0ad801278
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add filter

# [MS-DNSP] Block DNS Server Management over SMB named pipes (\PIPE\DNSSERVER)
add rule layer=um actiontype=block filterkey=50754fe4-aa2d-42ff-8196-e90ea8fd2527
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=50abc2a4-574d-40b3-9d66-ee4fd5fba076
add filter

# Block default Mimikatz MimiCom C2 interface (All transports)
add rule layer=um actiontype=block filterkey=644291ca-9530-4066-b654-e7b838ebdc06
add condition field=if_uuid matchtype=equal data=17FC11E9-C258-4B8D-8D07-2F4125156244
add filter

# [MS-FSRVP] Block File Server Remote VSS Protocol over SMB named pipes (\PIPE\FssagentRpc)
add rule layer=um actiontype=block filterkey=5270da6b-67a8-4cbf-8b2c-fa5d0abcb975
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=a8e0653c-2744-4389-a61d-7373df8b2292
add filter</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Deploy via GPO Startup Script</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the target Domain Controllers hardening GPO.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Scripts (Startup)</xhtml:code>
          </xhtml:li>
          <xhtml:li>Save <xhtml:code>RpcNamedPipesFilters.txt</xhtml:code> inside the GPO's Startup folder.</xhtml:li>
          <xhtml:li>Create a batch script named <xhtml:code>Import-RpcFilters.bat</xhtml:code> in the same directory:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>@echo off</xhtml:li>
          <xhtml:li>rem Import Windows Firewall RPC Named Pipe filters</xhtml:li>
          <xhtml:li>netsh.exe -f "%~dp0RpcNamedPipesFilters.txt"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Add <xhtml:code>Import-RpcFilters.bat</xhtml:code> to the GPO Startup Scripts list.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to deploy or verify the RPC named pipe filters.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-RpcNamedPipeFilters.ps1">Download Script: Set-RpcNamedPipeFilters.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-RpcNamedPipeFilters.ps1
# Description: Generates and imports RPC filters to block remote management and coercion over SMB named pipes.

Write-Host "Applying hardening requirement: Configure RPC Named Pipe Filters..." -ForegroundColor Cyan

# Define the path where the filters file will be written
$FilterFilePath = Join-Path $env:TEMP "RpcNamedPipesFilters.txt"

# Write the netsh RPC filter commands
$FilterContent = @"
rpc filter

# [MS-SCMR] Block Service Control Manager over SMB named pipes (\PIPE\svcctl)
add rule layer=um actiontype=block filterkey=d0c7640c-9355-4e52-8335-c12835559c10
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=367ABB81-9844-35F1-AD32-98F038001003
add filter

# [MS-TSCH] Block Task Scheduler Remoting over SMB named pipes (\PIPE\atsvc)
add rule layer=um actiontype=block filterkey=a43b9dd2-0866-4476-89dc-2e9b200762af
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=86D35949-83C9-4044-B424-DB363231FD0C
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 1 (All transports)
add rule layer=um actiontype=block filterkey=13518c11-e3d8-4f62-9461-eda11beb540a
add condition field=if_uuid matchtype=equal data=1FF70682-0A51-30E8-076D-740BE8CEE98B
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 2 (All transports)
add rule layer=um actiontype=block filterkey=1c079a18-e91f-4698-9868-68a121490636
add condition field=if_uuid matchtype=equal data=378E52B0-C0A9-11CF-822D-00AA0051E40F
add filter

# [MS-EVEN6] Block EventLog v6.0 Remoting over SMB named pipes (\PIPE\eventlog)
add rule layer=um actiontype=block filterkey=dedffabf-db89-4177-be77-1954aa2c0b95
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=f6beaff7-1e19-4fbb-9f8f-b89e2018337c
add filter

# [MS-EVEN] Block Legacy EventLog Remoting Protocol (All transports)
add rule layer=um actiontype=block filterkey=f7f68868-5f50-4cda-a18c-6a7a549652e7
add condition field=if_uuid matchtype=equal data=82273FDC-E32A-18C3-3F78-827929DC23EA
add filter

# [MS-DFSNM] Permit DFS Namespace Management exclusively for Domain Admins (\PIPE\netdfs)
add rule layer=um actiontype=permit filterkey=43873c58-e130-4ffb-8858-d259a673a917
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add condition field=remote_user_token matchtype=equal data=D:(A;;CC;;;DA)
add filter

# [MS-DFSNM] Block DFS Namespace Management for all other users
add rule layer=um actiontype=block filterkey=0a239867-73db-45e6-b287-d006fe3c8b18
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add filter

# [MS-RPRN] Block Print System Remote Protocol over SMB named pipes (\PIPE\spoolss)
add rule layer=um actiontype=block filterkey=7966512a-f2f4-4cb1-812d-d967ab83d28a
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=12345678-1234-ABCD-EF00-0123456789AB
add filter

# [MS-EFSR] Permit EFSRPC via lsarpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=d71d00db-3eef-4935-bedf-20cf628abd9e
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via lsarpc
add rule layer=um actiontype=block filterkey=3a4cce27-a7fa-4248-b8b8-ef6439a2c0ff
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add filter

# [MS-EFSR] Permit EFSRPC via efsrpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=c5cf8020-c83c-4803-9241-8c7f3b10171f
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via efsrpc
add rule layer=um actiontype=block filterkey=9ad23a91-085d-4f99-ae15-85e0ad801278
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add filter

# [MS-DNSP] Block DNS Server Management over SMB named pipes (\PIPE\DNSSERVER)
add rule layer=um actiontype=block filterkey=50754fe4-aa2d-42ff-8196-e90ea8fd2527
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=50abc2a4-574d-40b3-9d66-ee4fd5fba076
add filter

# Block default Mimikatz MimiCom C2 interface (All transports)
add rule layer=um actiontype=block filterkey=644291ca-9530-4066-b654-e7b838ebdc06
add condition field=if_uuid matchtype=equal data=17FC11E9-C258-4B8D-8D07-2F4125156244
add filter

# [MS-FSRVP] Block File Server Remote VSS Protocol over SMB named pipes (\PIPE\FssagentRpc)
add rule layer=um actiontype=block filterkey=5270da6b-67a8-4cbf-8b2c-fa5d0abcb975
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=a8e0653c-2744-4389-a61d-7373df8b2292
add filter
"@

# Write filters to temp file
Set-Content -Path $FilterFilePath -Value $FilterContent -Encoding Ascii
Write-Host "[+] Generated RPC filters definition file at: $FilterFilePath" -ForegroundColor Gray

# Import filters using netsh (requires administrative elevation)
Write-Host "[+] Importing RPC filters using Netsh..." -ForegroundColor Gray
$Proc = Start-Process -FilePath "netsh.exe" -ArgumentList "-f `"$FilterFilePath`"" -Wait -NoNewWindow -PassThru

if ($Proc.ExitCode -eq 0) {
    Write-Host "[+] RPC filters imported successfully." -ForegroundColor Green
} else {
    Write-Error "[-] Failed to import RPC filters. Netsh exit code: $($Proc.ExitCode)."
}

# Clean up temp file
if (Test-Path $FilterFilePath) {
    Remove-Item -Path $FilterFilePath -Force | Out-Null
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-RpcNamedPipeFilters.ps1">Download Script: Test-RpcNamedPipeFilters.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-RpcNamedPipeFilters.ps1
# Description: Audits active RPC filters configuration using Netsh queries.

Write-Host "Auditing RPC filters configuration..." -ForegroundColor Cyan

# Query active RPC filters
$filters = netsh.exe rpc filter show filter

# Define expected RPC filter rules with their metadata
$expectedRules = @(
    @{ FilterKey = "d0c7640c-9355-4e52-8335-c12835559c10"; Name = "MS-SCMR Service Control Manager (Block ncacn_np)"; Pipe = "\PIPE\svcctl" }
    @{ FilterKey = "a43b9dd2-0866-4476-89dc-2e9b200762af"; Name = "MS-TSCH Task Scheduler Remoting (Block ncacn_np)"; Pipe = "\PIPE\atsvc" }
    @{ FilterKey = "13518c11-e3d8-4f62-9461-eda11beb540a"; Name = "MS-TSCH Task Scheduler Legacy AT 1 (Block All)"; Pipe = "\PIPE\atsvc" }
    @{ FilterKey = "1c079a18-e91f-4698-9868-68a121490636"; Name = "MS-TSCH Task Scheduler Legacy AT 2 (Block All)"; Pipe = "\PIPE\atsvc" }
    @{ FilterKey = "dedffabf-db89-4177-be77-1954aa2c0b95"; Name = "MS-EVEN6 EventLog v6.0 Remoting (Block ncacn_np)"; Pipe = "\PIPE\eventlog" }
    @{ FilterKey = "f7f68868-5f50-4cda-a18c-6a7a549652e7"; Name = "MS-EVEN EventLog Legacy (Block All)"; Pipe = "\PIPE\eventlog" }
    @{ FilterKey = "43873c58-e130-4ffb-8858-d259a673a917"; Name = "MS-DFSNM DFS Namespace Mgmt (Permit Domain Admins)"; Pipe = "\PIPE\netdfs" }
    @{ FilterKey = "0a239867-73db-45e6-b287-d006fe3c8b18"; Name = "MS-DFSNM DFS Namespace Mgmt (Block Others)"; Pipe = "\PIPE\netdfs" }
    @{ FilterKey = "7966512a-f2f4-4cb1-812d-d967ab83d28a"; Name = "MS-RPRN Print System Remote (Block ncacn_np)"; Pipe = "\PIPE\spoolss" }
    @{ FilterKey = "d71d00db-3eef-4935-bedf-20cf628abd9e"; Name = "MS-EFSR via lsarpc (Permit Kerberos Encrypted)"; Pipe = "\PIPE\lsarpc" }
    @{ FilterKey = "3a4cce27-a7fa-4248-b8b8-ef6439a2c0ff"; Name = "MS-EFSR via lsarpc (Block Others)"; Pipe = "\PIPE\lsarpc" }
    @{ FilterKey = "c5cf8020-c83c-4803-9241-8c7f3b10171f"; Name = "MS-EFSR via efsrpc (Permit Kerberos Encrypted)"; Pipe = "\PIPE\efsrpc" }
    @{ FilterKey = "9ad23a91-085d-4f99-ae15-85e0ad801278"; Name = "MS-EFSR via efsrpc (Block Others)"; Pipe = "\PIPE\efsrpc" }
    @{ FilterKey = "50754fe4-aa2d-42ff-8196-e90ea8fd2527"; Name = "MS-DNSP DNS Server Remote Mgmt (Block ncacn_np)"; Pipe = "\PIPE\DNSSERVER" }
    @{ FilterKey = "644291ca-9530-4066-b654-e7b838ebdc06"; Name = "MimiCom Mimikatz Remote C2 (Block All)"; Pipe = "Any" }
    @{ FilterKey = "5270da6b-67a8-4cbf-8b2c-fa5d0abcb975"; Name = "MS-FSRVP File Server Remote VSS (Block ncacn_np)"; Pipe = "\PIPE\FssagentRpc" }
)

$missingFilters = @()
$activeFiltersCount = 0

# Join netsh output into a single string for fast and case-insensitive matching
$rawFiltersOutput = ($filters -join "`n").ToLowerInvariant()

foreach ($rule in $expectedRules) {
    $targetKey = $rule.FilterKey.ToLowerInvariant()
    if ($rawFiltersOutput.Contains($targetKey)) {
        $activeFiltersCount++
        Write-Host "[+] Active: $($rule.Name) [Key: $($rule.FilterKey)]" -ForegroundColor Green
    } else {
        $missingFilters += $rule
        Write-Host "[-] Missing: $($rule.Name) [Key: $($rule.FilterKey)]" -ForegroundColor Yellow
    }
}

Write-Host "`nSummary: $activeFiltersCount of $($expectedRules.Count) expected RPC filters are active." -ForegroundColor Cyan

if ($missingFilters.Count -eq 0) {
    Write-Host "[+] All 16 RPC named pipe filters are active and enforced." -ForegroundColor Green
    Write-Host "Audit result: COMPLIANT" -ForegroundColor Green
} else {
    Write-Host "[!] NON-COMPLIANT: $($missingFilters.Count) RPC named pipe filter rule(s) are missing or inactive." -ForegroundColor Red
    Write-Host "Audit result: NON-COMPLIANT" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-RpcNamedPipeFilters.ps1
# Description: Generates and imports RPC filters to block remote management and coercion over SMB named pipes.

Write-Host "Applying hardening requirement: Configure RPC Named Pipe Filters..." -ForegroundColor Cyan

# Define the path where the filters file will be written
$FilterFilePath = Join-Path $env:TEMP "RpcNamedPipesFilters.txt"

# Write the netsh RPC filter commands
$FilterContent = @"
rpc filter

# [MS-SCMR] Block Service Control Manager over SMB named pipes (\PIPE\svcctl)
add rule layer=um actiontype=block filterkey=d0c7640c-9355-4e52-8335-c12835559c10
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=367ABB81-9844-35F1-AD32-98F038001003
add filter

# [MS-TSCH] Block Task Scheduler Remoting over SMB named pipes (\PIPE\atsvc)
add rule layer=um actiontype=block filterkey=a43b9dd2-0866-4476-89dc-2e9b200762af
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=86D35949-83C9-4044-B424-DB363231FD0C
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 1 (All transports)
add rule layer=um actiontype=block filterkey=13518c11-e3d8-4f62-9461-eda11beb540a
add condition field=if_uuid matchtype=equal data=1FF70682-0A51-30E8-076D-740BE8CEE98B
add filter

# [MS-TSCH] Block Task Scheduler Legacy at.exe interface 2 (All transports)
add rule layer=um actiontype=block filterkey=1c079a18-e91f-4698-9868-68a121490636
add condition field=if_uuid matchtype=equal data=378E52B0-C0A9-11CF-822D-00AA0051E40F
add filter

# [MS-EVEN6] Block EventLog v6.0 Remoting over SMB named pipes (\PIPE\eventlog)
add rule layer=um actiontype=block filterkey=dedffabf-db89-4177-be77-1954aa2c0b95
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=f6beaff7-1e19-4fbb-9f8f-b89e2018337c
add filter

# [MS-EVEN] Block Legacy EventLog Remoting Protocol (All transports)
add rule layer=um actiontype=block filterkey=f7f68868-5f50-4cda-a18c-6a7a549652e7
add condition field=if_uuid matchtype=equal data=82273FDC-E32A-18C3-3F78-827929DC23EA
add filter

# [MS-DFSNM] Permit DFS Namespace Management exclusively for Domain Admins (\PIPE\netdfs)
add rule layer=um actiontype=permit filterkey=43873c58-e130-4ffb-8858-d259a673a917
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add condition field=remote_user_token matchtype=equal data=D:(A;;CC;;;DA)
add filter

# [MS-DFSNM] Block DFS Namespace Management for all other users
add rule layer=um actiontype=block filterkey=0a239867-73db-45e6-b287-d006fe3c8b18
add condition field=if_uuid matchtype=equal data=4FC742E0-4A10-11CF-8273-00AA004AE673
add filter

# [MS-RPRN] Block Print System Remote Protocol over SMB named pipes (\PIPE\spoolss)
add rule layer=um actiontype=block filterkey=7966512a-f2f4-4cb1-812d-d967ab83d28a
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=12345678-1234-ABCD-EF00-0123456789AB
add filter

# [MS-EFSR] Permit EFSRPC via lsarpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=d71d00db-3eef-4935-bedf-20cf628abd9e
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via lsarpc
add rule layer=um actiontype=block filterkey=3a4cce27-a7fa-4248-b8b8-ef6439a2c0ff
add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e
add filter

# [MS-EFSR] Permit EFSRPC via efsrpc only if Kerberos-authenticated and encrypted
add rule layer=um actiontype=permit filterkey=c5cf8020-c83c-4803-9241-8c7f3b10171f
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add condition field=auth_type matchtype=equal data=16
add condition field=auth_level matchtype=equal data=6
add filter

# [MS-EFSR] Block unencrypted or unauthenticated EFSRPC via efsrpc
add rule layer=um actiontype=block filterkey=9ad23a91-085d-4f99-ae15-85e0ad801278
add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d
add filter

# [MS-DNSP] Block DNS Server Management over SMB named pipes (\PIPE\DNSSERVER)
add rule layer=um actiontype=block filterkey=50754fe4-aa2d-42ff-8196-e90ea8fd2527
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=50abc2a4-574d-40b3-9d66-ee4fd5fba076
add filter

# Block default Mimikatz MimiCom C2 interface (All transports)
add rule layer=um actiontype=block filterkey=644291ca-9530-4066-b654-e7b838ebdc06
add condition field=if_uuid matchtype=equal data=17FC11E9-C258-4B8D-8D07-2F4125156244
add filter

# [MS-FSRVP] Block File Server Remote VSS Protocol over SMB named pipes (\PIPE\FssagentRpc)
add rule layer=um actiontype=block filterkey=5270da6b-67a8-4cbf-8b2c-fa5d0abcb975
add condition field=protocol matchtype=equal data=ncacn_np
add condition field=if_uuid matchtype=equal data=a8e0653c-2744-4389-a61d-7373df8b2292
add filter
"@

# Write filters to temp file
Set-Content -Path $FilterFilePath -Value $FilterContent -Encoding Ascii
Write-Host "[+] Generated RPC filters definition file at: $FilterFilePath" -ForegroundColor Gray

# Import filters using netsh (requires administrative elevation)
Write-Host "[+] Importing RPC filters using Netsh..." -ForegroundColor Gray
$Proc = Start-Process -FilePath "netsh.exe" -ArgumentList "-f `"$FilterFilePath`"" -Wait -NoNewWindow -PassThru

if ($Proc.ExitCode -eq 0) {
    Write-Host "[+] RPC filters imported successfully." -ForegroundColor Green
} else {
    Write-Error "[-] Failed to import RPC filters. Netsh exit code: $($Proc.ExitCode)."
}

# Clean up temp file
if (Test-Path $FilterFilePath) {
    Remove-Item -Path $FilterFilePath -Force | Out-Null
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4012" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-NET-013" severity="high" weight="10.0" selected="false">
      <title>[REQ-NET-013] Block Management Traffic Between Domain Controllers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>04-network-firewall/block-intra-dc-management.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Domain Controllers (DCs) represent the Tier 0 security boundary of an Active Directory forest. In a multi-DC environment, security controls must prevent lateral movement and credential escalation between these core servers.</xhtml:p>
        <xhtml:p>If an adversary gains administrative control of a single Domain Controller, they will immediately attempt to pivot to other DCs. By default, standard firewall configurations allow remote management protocols (RDP, WinRM, WMI) from all Tier 0 assets—including other Domain Controllers.</xhtml:p>
        <xhtml:p>Enforcing intra-DC remote management blocking resolves this vector: 1. <xhtml:strong>Lateral Movement Containment</xhtml:strong>: Restricting management traffic between DCs (e.g. blocking RDP TCP 3389, WinRM TCP 5985/5986, WMI TCP 24158, and ADWS TCP 9389 from other DC IP addresses) prevents a compromised DC from being used to compromise other domain controllers. 2. <xhtml:strong>Replication Integrity</xhtml:strong>: Normal Active Directory replication and synchronization protocols (RPC replication, DNS, Kerberos, SMB) remain open and unaffected, while administrative logon and command execution protocols are blocked. 3. <xhtml:strong>Zero Trust Tiering</xhtml:strong>: Assumes that even Tier 0 systems must not trust other Tier 0 systems for remote command execution.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Configure the Domain Controllers GPO to restrict source IP addresses for remote management rules:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting Domain Controllers (e.g., <xhtml:code>GPO_Hardening_DomainControllers_Firewall</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Under <xhtml:strong>Inbound Rules</xhtml:strong>, configure rules for remote management (RDP, WinRM, WMI, ADWS) to:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Allow connections originating only from </xhtml:em>
            <xhtml:em>Management/PAW subnets</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure that </xhtml:em>
            <xhtml:em>Domain Controller IP addresses</xhtml:em>* are explicitly excluded from the allowed remote address list.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Alternatively, create explicit inbound </xhtml:em>
            <xhtml:em>Block Rules</xhtml:em>* for ports <xhtml:code>3389</xhtml:code>, <xhtml:code>5985</xhtml:code>, <xhtml:code>5986</xhtml:code>, <xhtml:code>24158</xhtml:code>, and <xhtml:code>9389</xhtml:code> where the source IP addresses match the list of Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on each DC to implement and audit the block rules.</xhtml:p>
        <xhtml:h4>Remediation Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-IntraDcManagementBlocking.ps1">Download Script: Set-IntraDcManagementBlocking.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-IntraDcManagementBlocking.ps1
# Description: Configures local Windows Firewall rules to block remote management traffic (RDP, WinRM, WMI, ADWS) originating from other Domain Controllers to prevent lateral movement.

Write-Host "Applying hardening requirement: Block Management Traffic Between DCs..." -ForegroundColor Cyan

# 1. Get IP addresses of all Domain Controllers in the domain
$DcIPs = @()
try {
    $Dcs = Get-ADDomainController -Filter * -ErrorAction Stop
    foreach ($Dc in $Dcs) {
        # Skip local computer
        if ($Dc.Name -ne $env:COMPUTERNAME) {
            if ($Dc.IPv4Address) { $DcIPs += $Dc.IPv4Address }
            if ($Dc.IPv6Address) { $DcIPs += $Dc.IPv6Address }
        }
    }
} catch {
    Write-Host "    Get-ADDomainController not available or not in AD domain. Skipping dynamic discovery." -ForegroundColor Yellow
}

if ($DcIPs.Count -eq 0) {
    Write-Host "    No other Domain Controllers discovered. Blocking rule will be created but inactive." -ForegroundColor Yellow
    # Fallback to a dummy address to ensure rule structure is correct
    $DcIPs = @("255.255.255.255")
} else {
    Write-Host "    Discovered other DCs: $($DcIPs -join ', ')" -ForegroundColor Gray
}

# 2. Configure local block rules for DC-to-DC remote management
$BlockRules = @(
    @{ Name = "AD-Block-IntraDC-RDP"; Port = 3389; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WinRM-HTTP"; Port = 5985; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WinRM-HTTPS"; Port = 5986; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WMI"; Port = 24158; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-ADWS"; Port = 9389; Proto = "TCP" }
)

foreach ($Rule in $BlockRules) {
    $Name = $Rule.Name
    $Port = $Rule.Port
    $Proto = $Rule.Proto
    
    $Existing = Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -Name $Name -DisplayName $Name `
            -Direction Inbound `
            -Action Block `
            -Protocol $Proto `
            -LocalPort $Port `
            -RemoteAddress $DcIPs `
            -Profile Domain, Private `
            -Enabled True | Out-Null
        Write-Host "Block rule created: $($Name) on port $($Port) ($($Proto)) from other DCs." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -Name $Name -Enabled True -Action Block -RemoteAddress $DcIPs | Out-Null
        Write-Host "Block rule verified: $($Name) on port $($Port) ($($Proto)) from other DCs." -ForegroundColor Gray
    }
}

Write-Host "Intra-DC management blocking rules applied successfully." -ForegroundColor Cyan</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>Audit Script:</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-IntraDcManagementBlocking.ps1">Download Script: Test-IntraDcManagementBlocking.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-IntraDcManagementBlocking.ps1
# Description: Audits if management traffic from other Domain Controllers is blocked.

Write-Host "Auditing Intra-DC management blocking configurations..." -ForegroundColor Cyan

$vulnerable = $false
$BlockRules = @(
    "AD-Block-IntraDC-RDP",
    "AD-Block-IntraDC-WinRM-HTTP",
    "AD-Block-IntraDC-WinRM-HTTPS",
    "AD-Block-IntraDC-WMI",
    "AD-Block-IntraDC-ADWS"
)

foreach ($Name in $BlockRules) {
    $Rule = Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue
    if ($Rule) {
        if ($Rule.Enabled -eq $true -and $Rule.Action -eq "Block") {
            Write-Host "[+] Rule $($Name) is active and configured to Block." -ForegroundColor Green
        } else {
            Write-Host "[!] NON-COMPLIANT: Rule $($Name) exists but is disabled or not set to Block." -ForegroundColor Red
            $vulnerable = $true
        }
    } else {
        Write-Host "[!] NON-COMPLIANT: Block rule $($Name) is missing." -ForegroundColor Red
        $vulnerable = $true
    }
}

if ($vulnerable) {
    Write-Host "Audit result: NON-COMPLIANT" -ForegroundColor Red
} else {
    Write-Host "Audit result: COMPLIANT" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-IntraDcManagementBlocking.ps1
# Description: Configures local Windows Firewall rules to block remote management traffic (RDP, WinRM, WMI, ADWS) originating from other Domain Controllers to prevent lateral movement.

Write-Host "Applying hardening requirement: Block Management Traffic Between DCs..." -ForegroundColor Cyan

# 1. Get IP addresses of all Domain Controllers in the domain
$DcIPs = @()
try {
    $Dcs = Get-ADDomainController -Filter * -ErrorAction Stop
    foreach ($Dc in $Dcs) {
        # Skip local computer
        if ($Dc.Name -ne $env:COMPUTERNAME) {
            if ($Dc.IPv4Address) { $DcIPs += $Dc.IPv4Address }
            if ($Dc.IPv6Address) { $DcIPs += $Dc.IPv6Address }
        }
    }
} catch {
    Write-Host "    Get-ADDomainController not available or not in AD domain. Skipping dynamic discovery." -ForegroundColor Yellow
}

if ($DcIPs.Count -eq 0) {
    Write-Host "    No other Domain Controllers discovered. Blocking rule will be created but inactive." -ForegroundColor Yellow
    # Fallback to a dummy address to ensure rule structure is correct
    $DcIPs = @("255.255.255.255")
} else {
    Write-Host "    Discovered other DCs: $($DcIPs -join ', ')" -ForegroundColor Gray
}

# 2. Configure local block rules for DC-to-DC remote management
$BlockRules = @(
    @{ Name = "AD-Block-IntraDC-RDP"; Port = 3389; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WinRM-HTTP"; Port = 5985; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WinRM-HTTPS"; Port = 5986; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-WMI"; Port = 24158; Proto = "TCP" },
    @{ Name = "AD-Block-IntraDC-ADWS"; Port = 9389; Proto = "TCP" }
)

foreach ($Rule in $BlockRules) {
    $Name = $Rule.Name
    $Port = $Rule.Port
    $Proto = $Rule.Proto
    
    $Existing = Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -Name $Name -DisplayName $Name `
            -Direction Inbound `
            -Action Block `
            -Protocol $Proto `
            -LocalPort $Port `
            -RemoteAddress $DcIPs `
            -Profile Domain, Private `
            -Enabled True | Out-Null
        Write-Host "Block rule created: $($Name) on port $($Port) ($($Proto)) from other DCs." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -Name $Name -Enabled True -Action Block -RemoteAddress $DcIPs | Out-Null
        Write-Host "Block rule verified: $($Name) on port $($Port) ($($Proto)) from other DCs." -ForegroundColor Gray
    }
}

Write-Host "Intra-DC management blocking rules applied successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:4013" />
      </check>
    </Rule>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_5__Logging__Monitoring___SIEM">
    <title>Module 5: Logging, Monitoring &amp; SIEM</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-LOG-001] Configure Advanced Security Audit Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/configure-advanced-audit-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Standard Windows security event logging is basic and fails to capture critical event vectors, leading to visibility gaps during compromises. Enforcing refined subcategory audit policies ensures detailed Success and Failure logs for logon attempts, privilege use, process creations, and registry modifications without overloading log stores.</xhtml:p>
        <xhtml:p>This requirement acts as the primary logging baseline, enforcing category overrides and linking to profile-specific submodules matching each system's security tier.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the corresponding baseline GPO (e.g. <xhtml:code>GPO_Hardening_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-AdvancedAuditPolicies.ps1">Download Script: Configure-AdvancedAuditPolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-AdvancedAuditPolicies.ps1
# Description: Enforces Advanced Audit Policy Overrides registry value.

$RegPath = "reg:\HKLM\System\CurrentControlSet\Control\Lsa"
$ValueName = "SCENoApplyLegacyAuditPolicy"

Write-Host "Enforcing Advanced Security Audit Policies override settings..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -Force
Write-Host "Advanced Audit Policy overrides enforced successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-AdvancedAuditPoliciesStatus.ps1">Download Script: Get-AdvancedAuditPoliciesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-AdvancedAuditPoliciesStatus.ps1
# Description: Audits the Advanced Audit Policy Overrides registry value.

$RegPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$ValueName = "SCENoApplyLegacyAuditPolicy"

$val = Get-ItemPropertyValue -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
if ($val -eq 1) {
    Write-Host "Advanced Security Audit Policy Overrides are correctly enabled." -ForegroundColor Green
} else {
    Write-Host "Advanced Security Audit Policy Overrides are disabled!" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-AdvancedAuditPolicies.ps1
# Description: Enforces Advanced Audit Policy Overrides registry value.

$RegPath = "reg:\HKLM\System\CurrentControlSet\Control\Lsa"
$ValueName = "SCENoApplyLegacyAuditPolicy"

Write-Host "Enforcing Advanced Security Audit Policies override settings..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -Force
Write-Host "Advanced Audit Policy overrides enforced successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-LOG-002] Configure PowerShell and Command-Line Auditing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/configure-powershell-and-command-line-auditing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Adversaries make extensive use of built-in system tools (LOLBins) and PowerShell script execution to perform reconnaissance, privilege escalation, and lateral movement. Because PowerShell code can be dynamically obfuscated or executed directly in memory without writing to disk, traditional file-based detection mechanisms are easily bypassed.</xhtml:p>
        <xhtml:p>Enforcing advanced execution logging mitigates these threat vectors: 1. <xhtml:strong>Command Line Auditing</xhtml:strong>: Injecting command-line arguments into Security Event ID 4688 allows defenders to see parameters, file paths, and encoded arguments used during process execution. 2. <xhtml:strong>Script Block Logging</xhtml:strong>: Captures the full content of code blocks executed by PowerShell (Event ID 4104), logging the actual code after decryption and de-obfuscation at runtime. 3. <xhtml:strong>Module Logging</xhtml:strong>: Logs pipeline execution details and loaded modules (Event ID 4103) to map tool usage. 4. <xhtml:strong>Hardened Transcription</xhtml:strong>: Records all input commands and console outputs to local text transcripts. By restricting folder access permissions, users are blocked from reading previously typed commands (which may contain sensitive arguments, tokens, or credentials), while still allowing the system to log their actions.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure Process Command-Line Logging</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to target systems (e.g., <xhtml:code>GPO_Hardening_Logging_Baseline</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Audit Process Creation</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Include command line in process creation events</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure PowerShell Audit Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows PowerShell</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure <xhtml:strong>Script Block Logging</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn on PowerShell Script Block Logging</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>
            <xhtml:em>: `Enabled` (Ensure </xhtml:em>
            <xhtml:em>Log script block invocation start / stop events</xhtml:em>
            <xhtml:em> is </xhtml:em>
            <xhtml:em>unchecked</xhtml:em>* / disabled to prevent operational log flooding)</xhtml:li>
          <xhtml:li>Configure <xhtml:strong>Module Logging</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn on PowerShell Module Logging</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>
            <xhtml:em>: `Enabled` -&gt; Click </xhtml:em>
            <xhtml:em>Show...</xhtml:em>
            <xhtml:em> -&gt; Add `</xhtml:em>` under Value.</xhtml:li>
          <xhtml:li>Configure <xhtml:strong>PowerShell Transcription</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn on PowerShell Transcription</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Transcript output directory</xhtml:em>*: <xhtml:code>C:\ProgramData\PowerShellTranscripts</xhtml:code> (Ensure this is a local path)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Include invocation headers</xhtml:em>*: Checked</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure command line process creation, PowerShell logging registry keys, and create the hardened transcript directory with write-only NTFS permissions.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PowerShellAuditing.ps1">Download Script: Set-PowerShellAuditing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PowerShellAuditing.ps1
# Configures command line auditing, PowerShell logging, transcription, and hardens folder ACLs.

Write-Host "--- Applying PowerShell &amp; Command Line Auditing Remediation ---" -ForegroundColor Cyan

# 1. Enable Process Creation Command-Line Auditing
Write-Host "[+] Configuring Command Line Process Auditing..." -ForegroundColor Gray
$ProcAuditReg = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"
if (-not (Test-Path $ProcAuditReg)) {
    New-Item -Path $ProcAuditReg -Force | Out-Null
}
Set-ItemProperty -Path $ProcAuditReg -Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -Type DWord
Write-Host "    Command line process auditing enabled." -ForegroundColor Green

# 2. Configure PowerShell Script Block Logging
Write-Host "[+] Configuring PowerShell Script Block Logging..." -ForegroundColor Gray
$ScriptBlockReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (-not (Test-Path $ScriptBlockReg)) {
    New-Item -Path $ScriptBlockReg -Force | Out-Null
}
Set-ItemProperty -Path $ScriptBlockReg -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
Set-ItemProperty -Path $ScriptBlockReg -Name "EnableScriptBlockInvocationLogging" -Value 0 -Type DWord
Write-Host "    PowerShell Script Block Logging enabled and invocation start/stop logging disabled." -ForegroundColor Green

# 3. Configure PowerShell Module Logging
Write-Host "[+] Configuring PowerShell Module Logging..." -ForegroundColor Gray
$ModuleReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
if (-not (Test-Path $ModuleReg)) {
    New-Item -Path $ModuleReg -Force | Out-Null
}
Set-ItemProperty -Path $ModuleReg -Name "EnableModuleLogging" -Value 1 -Type DWord

$ModuleNamesReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames"
if (-not (Test-Path $ModuleNamesReg)) {
    New-Item -Path $ModuleNamesReg -Force | Out-Null
}
Set-ItemProperty -Path $ModuleNamesReg -Name "*" -Value "*" -Type String
Write-Host "    PowerShell Module Logging enabled for all modules." -ForegroundColor Green

# 4. Configure PowerShell Transcription
Write-Host "[+] Configuring PowerShell Transcription Registry settings..." -ForegroundColor Gray
$TransReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription"
if (-not (Test-Path $TransReg)) {
    New-Item -Path $TransReg -Force | Out-Null
}
$TranscriptPath = "C:\ProgramData\PowerShellTranscripts"
Set-ItemProperty -Path $TransReg -Name "EnableTranscripting" -Value 1 -Type DWord
Set-ItemProperty -Path $TransReg -Name "EnableInvocationHeader" -Value 1 -Type DWord
Set-ItemProperty -Path $TransReg -Name "OutputDirectory" -Value $TranscriptPath -Type String
Write-Host "    PowerShell Transcription registry keys configured." -ForegroundColor Green

# 5. Create and Harden PowerShell Transcript Folder
Write-Host "[+] Setting up hardened NTFS permissions on $($TranscriptPath)..." -ForegroundColor Gray
if (-not (Test-Path $TranscriptPath)) {
    New-Item -Path $TranscriptPath -ItemType Directory -Force | Out-Null
}

# Fetch ACL and disable inheritance, copying existing rules
$Acl = Get-Acl -Path $TranscriptPath
$Acl.SetAccessRuleProtection($true, $true)
Set-Acl -Path $TranscriptPath -AclObject $Acl

# Refresh ACL and remove user/authenticated user permissions
$Acl = Get-Acl -Path $TranscriptPath
$Rules = $Acl.Access
foreach ($Rule in $Rules) {
    $Identity = $Rule.IdentityReference.Value
    if ($Identity -like "*Users" -or $Identity -like "*Authenticated Users" -or $Identity -like "*Everyone") {
        $Acl.RemoveAccessRule($Rule) | Out-Null
    }
}

# Define write-only permissions for Authenticated Users
# CreateFiles/AppendData allows logging, while missing ListDirectory/ReadData blocks viewing transcripts.
$WriteRights = [System.Security.AccessControl.FileSystemRights]("CreateFiles, AppendData, ReadAttributes, WriteAttributes")
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]("ContainerInherit, ObjectInherit")
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
$AccessType = [System.Security.AccessControl.AccessControlType]::Allow

$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\Authenticated Users", $WriteRights, $InheritanceFlags, $PropagationFlags, $AccessType)
$Acl.AddAccessRule($AccessRule)
Set-Acl -Path $TranscriptPath -AclObject $Acl
Write-Host "    Hardened NTFS permissions applied to $($TranscriptPath) successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PowerShellAuditing.ps1">Download Script: Test-PowerShellAuditing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PowerShellAuditing.ps1
# Audits command line process creation, PowerShell logging, and transcript folder permissions.

Write-Host "--- Auditing PowerShell &amp; Command Line Auditing ---" -ForegroundColor Cyan

# 1. Audit Process Command-Line Logging
$ProcPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"
$CmdLineVal = Get-ItemProperty -Path $ProcPath -Name "ProcessCreationIncludeCmdLine_Enabled" -ErrorAction SilentlyContinue
$CmdSetting = 0
if ($CmdLineVal) {
    $CmdSetting = $CmdLineVal.ProcessCreationIncludeCmdLine_Enabled
}
$CmdColor = "Red"
if ($CmdSetting -eq 1) {
    $CmdColor = "Green"
}
Write-Host "    - Command Line Process Auditing: $($CmdSetting) (Required = 1)" -ForegroundColor $CmdColor

# 2. Audit Script Block Logging
$SBPath = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
$SBVal = Get-ItemProperty -Path $SBPath -Name "EnableScriptBlockLogging" -ErrorAction SilentlyContinue
$SBSetting = 0
if ($SBVal) {
    $SBSetting = $SBVal.EnableScriptBlockLogging
}
$SBColor = "Red"
if ($SBSetting -eq 1) {
    $SBColor = "Green"
}
Write-Host "    - PowerShell Script Block Logging: $($SBSetting) (Required = 1)" -ForegroundColor $SBColor

$SBInvVal = Get-ItemProperty -Path $SBPath -Name "EnableScriptBlockInvocationLogging" -ErrorAction SilentlyContinue
$SBInvSetting = 0
if ($SBInvVal) {
    $SBInvSetting = $SBInvVal.EnableScriptBlockInvocationLogging
}
$SBInvColor = "Red"
if ($SBInvSetting -eq 0) {
    $SBInvColor = "Green"
}
Write-Host "    - PowerShell Script Block Invocation Logging (Start/Stop): $($SBInvSetting) (Required = 0)" -ForegroundColor $SBInvColor

# 3. Audit Module Logging
$ModPath = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
$ModVal = Get-ItemProperty -Path $ModPath -Name "EnableModuleLogging" -ErrorAction SilentlyContinue
$ModSetting = 0
if ($ModVal) {
    $ModSetting = $ModVal.EnableModuleLogging
}
$ModColor = "Red"
if ($ModSetting -eq 1) {
    $ModColor = "Green"
}
Write-Host "    - PowerShell Module Logging: $($ModSetting) (Required = 1)" -ForegroundColor $ModColor

# 4. Audit Transcription Setup
$TransPath = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription"
$TransVal = Get-ItemProperty -Path $TransPath -Name "EnableTranscripting" -ErrorAction SilentlyContinue
$TransSetting = 0
if ($TransVal) {
    $TransSetting = $TransVal.EnableTranscripting
}
$TransColor = "Red"
if ($TransSetting -eq 1) {
    $TransColor = "Green"
}
Write-Host "    - PowerShell Transcription Enabled: $($TransSetting) (Required = 1)" -ForegroundColor $TransColor

$TransDirVal = Get-ItemProperty -Path $TransPath -Name "OutputDirectory" -ErrorAction SilentlyContinue
$TransDir = ""
if ($TransDirVal) {
    $TransDir = $TransDirVal.OutputDirectory
}
$DirColor = if ($TransDir) { "Green" } else { "Red" }
Write-Host "    - PowerShell Transcription Directory: $($TransDir)" -ForegroundColor $DirColor

# 5. Audit Transcript Folder Security Permissions
if ($TransDir) {
    if (-not (Test-Path $TransDir)) {
        Write-Host "    - Transcription directory does not exist locally." -ForegroundColor Red
    } else {
        $Acl = Get-Acl -Path $TransDir
        $Rules = $Acl.Access
        $HasUnsafeRead = $false
        $HasWriteOnly = $false
        
        foreach ($Rule in $Rules) {
            $Identity = $Rule.IdentityReference.Value
            $Rights = $Rule.FileSystemRights
            $Type = $Rule.AccessControlType
            
            if ($Type -eq "Allow" -and ($Identity -like "*Authenticated Users" -or $Identity -like "*Users" -or $Identity -like "*Everyone")) {
                # Look for read access
                $UnsafeRights = @("ReadData", "ListDirectory", "FullControl", "Modify", "Delete", "ReadAndExecute", "Read")
                foreach ($Right in $UnsafeRights) {
                    if ($Rights.ToString() -match $Right) {
                        $HasUnsafeRead = $true
                    }
                }
                
                # Check for write-only parameters
                if ($Rights.ToString() -match "CreateFiles" -and $Rights.ToString() -match "AppendData" -and -not ($Rights.ToString() -match "ReadData")) {
                    $HasWriteOnly = $true
                }
            }
        }
        
        $AclColor = "Red"
        if ($HasWriteOnly -and -not $HasUnsafeRead) {
            $AclColor = "Green"
        }
        Write-Host "    - Transcript Folder Security: WriteOnly=$($HasWriteOnly), UnsafeReadAccess=$($HasUnsafeRead)" -ForegroundColor $AclColor
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PowerShellAuditing.ps1
# Configures command line auditing, PowerShell logging, transcription, and hardens folder ACLs.

Write-Host "--- Applying PowerShell &amp; Command Line Auditing Remediation ---" -ForegroundColor Cyan

# 1. Enable Process Creation Command-Line Auditing
Write-Host "[+] Configuring Command Line Process Auditing..." -ForegroundColor Gray
$ProcAuditReg = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"
if (-not (Test-Path $ProcAuditReg)) {
    New-Item -Path $ProcAuditReg -Force | Out-Null
}
Set-ItemProperty -Path $ProcAuditReg -Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -Type DWord
Write-Host "    Command line process auditing enabled." -ForegroundColor Green

# 2. Configure PowerShell Script Block Logging
Write-Host "[+] Configuring PowerShell Script Block Logging..." -ForegroundColor Gray
$ScriptBlockReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (-not (Test-Path $ScriptBlockReg)) {
    New-Item -Path $ScriptBlockReg -Force | Out-Null
}
Set-ItemProperty -Path $ScriptBlockReg -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
Set-ItemProperty -Path $ScriptBlockReg -Name "EnableScriptBlockInvocationLogging" -Value 0 -Type DWord
Write-Host "    PowerShell Script Block Logging enabled and invocation start/stop logging disabled." -ForegroundColor Green

# 3. Configure PowerShell Module Logging
Write-Host "[+] Configuring PowerShell Module Logging..." -ForegroundColor Gray
$ModuleReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
if (-not (Test-Path $ModuleReg)) {
    New-Item -Path $ModuleReg -Force | Out-Null
}
Set-ItemProperty -Path $ModuleReg -Name "EnableModuleLogging" -Value 1 -Type DWord

$ModuleNamesReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames"
if (-not (Test-Path $ModuleNamesReg)) {
    New-Item -Path $ModuleNamesReg -Force | Out-Null
}
Set-ItemProperty -Path $ModuleNamesReg -Name "*" -Value "*" -Type String
Write-Host "    PowerShell Module Logging enabled for all modules." -ForegroundColor Green

# 4. Configure PowerShell Transcription
Write-Host "[+] Configuring PowerShell Transcription Registry settings..." -ForegroundColor Gray
$TransReg = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription"
if (-not (Test-Path $TransReg)) {
    New-Item -Path $TransReg -Force | Out-Null
}
$TranscriptPath = "C:\ProgramData\PowerShellTranscripts"
Set-ItemProperty -Path $TransReg -Name "EnableTranscripting" -Value 1 -Type DWord
Set-ItemProperty -Path $TransReg -Name "EnableInvocationHeader" -Value 1 -Type DWord
Set-ItemProperty -Path $TransReg -Name "OutputDirectory" -Value $TranscriptPath -Type String
Write-Host "    PowerShell Transcription registry keys configured." -ForegroundColor Green

# 5. Create and Harden PowerShell Transcript Folder
Write-Host "[+] Setting up hardened NTFS permissions on $($TranscriptPath)..." -ForegroundColor Gray
if (-not (Test-Path $TranscriptPath)) {
    New-Item -Path $TranscriptPath -ItemType Directory -Force | Out-Null
}

# Fetch ACL and disable inheritance, copying existing rules
$Acl = Get-Acl -Path $TranscriptPath
$Acl.SetAccessRuleProtection($true, $true)
Set-Acl -Path $TranscriptPath -AclObject $Acl

# Refresh ACL and remove user/authenticated user permissions
$Acl = Get-Acl -Path $TranscriptPath
$Rules = $Acl.Access
foreach ($Rule in $Rules) {
    $Identity = $Rule.IdentityReference.Value
    if ($Identity -like "*Users" -or $Identity -like "*Authenticated Users" -or $Identity -like "*Everyone") {
        $Acl.RemoveAccessRule($Rule) | Out-Null
    }
}

# Define write-only permissions for Authenticated Users
# CreateFiles/AppendData allows logging, while missing ListDirectory/ReadData blocks viewing transcripts.
$WriteRights = [System.Security.AccessControl.FileSystemRights]("CreateFiles, AppendData, ReadAttributes, WriteAttributes")
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]("ContainerInherit, ObjectInherit")
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
$AccessType = [System.Security.AccessControl.AccessControlType]::Allow

$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\Authenticated Users", $WriteRights, $InheritanceFlags, $PropagationFlags, $AccessType)
$Acl.AddAccessRule($AccessRule)
Set-Acl -Path $TranscriptPath -AclObject $Acl
Write-Host "    Hardened NTFS permissions applied to $($TranscriptPath) successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-003" severity="medium" weight="10.0" selected="false">
      <title>[REQ-LOG-003] Deploy and Harden Microsoft Sysmon</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/deploy-and-harden-sysmon.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Security event logs lack detailed telemetry on low-level operating system actions, such as process memory reads (e.g., LSASS dumping via Mimikatz), thread injection, network connections associated with process IDs, and driver loading. Microsoft Sysmon (System Monitor) bridges this gap by writing rich system monitoring telemetry to the <xhtml:code>Microsoft-Windows-Sysmon/Operational</xhtml:code> event log channel.</xhtml:p>
        <xhtml:p>Because Sysmon is a critical detection source, adversaries actively target it by attempting to unload its filter driver (<xhtml:code>sysmon -u</xhtml:code> or <xhtml:code>fltmc unload SysmonDrv</xhtml:code>) or stopping/disabling the Sysmon service (<xhtml:code>sc stop Sysmon</xhtml:code>).</xhtml:p>
        <xhtml:p>Hardening Sysmon involves: 1. <xhtml:strong>Service Recovery Configuration</xhtml:strong>: Forcing the operating system to automatically restart the Sysmon service on failure or termination. 2. <xhtml:strong>Telemetry Filtering</xhtml:strong>: Deploying a hardened, security-focused XML configuration template that filters out noise while logging process creation (Event ID 1), remote threads (Event ID 8), LSASS memory access (Event ID 10), and suspicious file drops (Event ID 11).</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Installation and Service Configuration</xhtml:h3>
        <xhtml:h4>1. Install Sysmon with Hardened XML Base Configuration</xhtml:h4>
        <xhtml:p>Deploy Sysmon using the command line with a local XML configuration file. Save the following template as <xhtml:code>sysmon-config.xml</xhtml:code> in a secure administrative path:</xhtml:p>
        <xhtml:pre>
          <xhtml:code>&lt;Sysmon schemaversion="4.50"&gt;
  &lt;HashAlgorithms&gt;md5,sha256,imphash&lt;/HashAlgorithms&gt;
  &lt;EventFiltering&gt;
    &lt;!-- Rule Group: Process Creation (Event ID 1) --&gt;
    &lt;RuleGroup name="Process Creation" groupRelation="or"&gt;
      &lt;ProcessCreate onmatch="exclude" /&gt;
    &lt;/RuleGroup&gt;
    
    &lt;!-- Rule Group: Network Connections (Event ID 3) --&gt;
    &lt;RuleGroup name="Network Connection" groupRelation="or"&gt;
      &lt;NetworkConnect onmatch="include"&gt;
        &lt;DestinationPort condition="is"&gt;22&lt;/DestinationPort&gt;
        &lt;DestinationPort condition="is"&gt;3389&lt;/DestinationPort&gt;
        &lt;DestinationPort condition="is"&gt;445&lt;/DestinationPort&gt;
        &lt;DestinationPort condition="is"&gt;5985&lt;/DestinationPort&gt;
        &lt;DestinationPort condition="is"&gt;5986&lt;/DestinationPort&gt;
      &lt;/NetworkConnect&gt;
    &lt;/RuleGroup&gt;

    &lt;!-- Rule Group: Driver Load (Event ID 6) --&gt;
    &lt;RuleGroup name="Driver Load" groupRelation="or"&gt;
      &lt;DriverLoad onmatch="exclude" /&gt;
    &lt;/RuleGroup&gt;

    &lt;!-- Rule Group: CreateRemoteThread (Event ID 8) --&gt;
    &lt;RuleGroup name="CreateRemoteThread" groupRelation="or"&gt;
      &lt;CreateRemoteThread onmatch="include"&gt;
        &lt;TargetImage condition="end with"&gt;lsass.exe&lt;/TargetImage&gt;
        &lt;TargetImage condition="end with"&gt;spoolsv.exe&lt;/TargetImage&gt;
      &lt;/CreateRemoteThread&gt;
    &lt;/RuleGroup&gt;

    &lt;!-- Rule Group: Process Access (Event ID 10) --&gt;
    &lt;RuleGroup name="Process Access" groupRelation="or"&gt;
      &lt;ProcessAccess onmatch="include"&gt;
        &lt;TargetImage condition="end with"&gt;lsass.exe&lt;/TargetImage&gt;
      &lt;/ProcessAccess&gt;
    &lt;/RuleGroup&gt;

    &lt;!-- Rule Group: File Creation (Event ID 11) --&gt;
    &lt;RuleGroup name="File Creation" groupRelation="or"&gt;
      &lt;FileCreate onmatch="include"&gt;
        &lt;TargetFilename condition="contains"&gt;\Startup\&lt;/TargetFilename&gt;
        &lt;TargetFilename condition="end with"&gt;.exe&lt;/TargetFilename&gt;
        &lt;TargetFilename condition="end with"&gt;.ps1&lt;/TargetFilename&gt;
        &lt;TargetFilename condition="end with"&gt;.bat&lt;/TargetFilename&gt;
      &lt;/FileCreate&gt;
    &lt;/RuleGroup&gt;
  &lt;/EventFiltering&gt;
&lt;/Sysmon&gt;</xhtml:code>
        </xhtml:pre>
        <xhtml:p>Run the installer via administrative command line: <xhtml:code />
          <xhtml:code>cmd Sysmon64.exe -i sysmon-config.xml -accepteula </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:h4>2. Enforce Service Recovery settings</xhtml:h4>
        <xhtml:p>Configure the Windows Service Control Manager to automatically restart the Sysmon service if it is terminated: <xhtml:code />
          <xhtml:code>cmd sc.exe failure Sysmon actions= restart/60000/restart/60000/restart/60000 reset= 86400 </xhtml:code>
          <xhtml:code />
          <xhtml:em>(Note: Ensure there is a space after the `=` sign for both parameters).</xhtml:em>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to deploy/configure Sysmon and verify its operational state.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-SysmonHardening.ps1">Download Script: Set-SysmonHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-SysmonHardening.ps1
# Configures Sysmon service recovery settings.

Write-Host "--- Hardening Sysmon Service Recovery Settings ---" -ForegroundColor Cyan

# 1. Ensure Sysmon Service is installed and configured
$SysmonService = Get-Service -Name "Sysmon" -ErrorAction SilentlyContinue
if (-not $SysmonService) {
    Write-Warning "Sysmon service is not currently installed. Run the Sysmon installer first."
    exit 1
}

# 2. Configure Service Failure Recovery options via sc.exe
Write-Host "[+] Configuring service failure recovery actions for Sysmon..." -ForegroundColor Gray
$ScArgs = "failure Sysmon actions= restart/60000/restart/60000/restart/60000 reset= 86400"
$Process = Start-Process sc.exe -ArgumentList $ScArgs -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Sysmon service recovery actions successfully set to auto-restart." -ForegroundColor Green
} else {
    Write-Error "    Failed to set service recovery settings. Exit Code: $($Process.ExitCode)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-SysmonHardening.ps1">Download Script: Test-SysmonHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-SysmonHardening.ps1
# Audits Sysmon service, driver execution, and recovery actions.

Write-Host "--- Auditing Sysmon Hardening State ---" -ForegroundColor Cyan

# 1. Verify Sysmon Service status
$SysmonService = Get-Service -Name "Sysmon" -ErrorAction SilentlyContinue
$ServiceStatus = "Stopped"
if ($SysmonService) {
    $ServiceStatus = $SysmonService.Status
}
$ServiceColor = if ($ServiceStatus -eq "Running") { "Green" } else { "Red" }
Write-Host "    - Sysmon Service Status: $($ServiceStatus) (Required = Running)" -ForegroundColor $ServiceColor

# 2. Verify Sysmon Filter Driver (SysmonDrv)
$DriverRunning = $false
$DriverCheck = fltmc.exe filters
foreach ($Line in $DriverCheck) {
    if ($Line -match "SysmonDrv") {
        $DriverRunning = $true
    }
}
$DriverColor = if ($DriverRunning) { "Green" } else { "Red" }
Write-Host "    - Sysmon Kernel Driver Loaded: $($DriverRunning) (Required = True)" -ForegroundColor $DriverColor

# 3. Verify Service Failure Recovery Options
$FailureInfo = sc.exe qfailure Sysmon
$HasReset = $false
$HasRestart = $false
foreach ($Line in $FailureInfo) {
    if ($Line -match "RESET_PERIOD\s+:\s+86400") {
        $HasReset = $true
    }
    if ($Line -match "FAILURE_ACTIONS\s+:\s+RESTART") {
        $HasRestart = $true
    }
}

$RecoveryColor = if ($HasReset -and $HasRestart) { "Green" } else { "Red" }
Write-Host "    - Recovery Configuration: ResetConfigured=$($HasReset), RestartActionsConfigured=$($HasRestart)" -ForegroundColor $RecoveryColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-SysmonHardening.ps1
# Configures Sysmon service recovery settings.

Write-Host "--- Hardening Sysmon Service Recovery Settings ---" -ForegroundColor Cyan

# 1. Ensure Sysmon Service is installed and configured
$SysmonService = Get-Service -Name "Sysmon" -ErrorAction SilentlyContinue
if (-not $SysmonService) {
    Write-Warning "Sysmon service is not currently installed. Run the Sysmon installer first."
    exit 1
}

# 2. Configure Service Failure Recovery options via sc.exe
Write-Host "[+] Configuring service failure recovery actions for Sysmon..." -ForegroundColor Gray
$ScArgs = "failure Sysmon actions= restart/60000/restart/60000/restart/60000 reset= 86400"
$Process = Start-Process sc.exe -ArgumentList $ScArgs -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Sysmon service recovery actions successfully set to auto-restart." -ForegroundColor Green
} else {
    Write-Error "    Failed to set service recovery settings. Exit Code: $($Process.ExitCode)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-004" severity="medium" weight="10.0" selected="false">
      <title>[REQ-LOG-004] Configure Secure SIEM Log Shipping</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 (and above), Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/configure-siem-log-shipping.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In high-security, isolated environments, local log storage is vulnerable to tampering. Attackers who obtain elevated privileges will attempt to clear or modify the Security Event Logs (e.g., via <xhtml:code>wevtutil cl Security</xhtml:code>) to destroy evidence of their activities. Shipping event logs in real-time to a dedicated offline SIEM (such as an ELK Stack or Wazuh Manager) ensures that forensic logs are preserved.</xhtml:p>
        <xhtml:p>To prevent adversaries from intercepting, redirecting, or tampering with log telemetry, log shippers must be hardened: 1. <xhtml:strong>Secure Transportation (TLS)</xhtml:strong>: Enforce TLS 1.2 or TLS 1.3 encryption with strict verification of the server certificate authority. This prevents man-in-the-middle attacks where an adversary redirects logs to a rogue listener. 2. <xhtml:strong>Buffer and Queue Management</xhtml:strong>: Limit memory and disk spool queues for the shipping agents. If the SIEM receiver goes offline during maintenance or network failure, the agents must cache logs safely without causing memory leaks, high CPU overhead, or local disk exhaustion. 3. <xhtml:strong>Hardened Configuration Files</xhtml:strong>: Agent configurations contain hostnames, ports, and potentially credentials or internal CA paths. Restricting access to these configuration files prevents standard users from discovering SIEM endpoints or tampering with configuration parameters.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Agent Configuration</xhtml:h3>
        <xhtml:h4>1. Secure Winlogbeat Configuration</xhtml:h4>
        <xhtml:p>Edit <xhtml:code>winlogbeat.yml</xhtml:code> (located by default under <xhtml:code>%ProgramFiles%\Winlogbeat\winlogbeat.yml</xhtml:code>) to enforce TLS 1.2/1.3, configure local queue limits, and forward the key log channels:</xhtml:p>
        <xhtml:pre>
          <xhtml:code>winlogbeat.event_logs:
  - name: Security
  - name: System
  - name: Microsoft-Windows-Sysmon/Operational
  - name: Microsoft-Windows-PowerShell/Operational

# Enforce disk-assisted memory queue limits to prevent memory exhaustion
queue.mem:
  events: 4096
  flush.min_events: 2048
  flush.timeout: 1s

# Output to Logstash/SIEM with TLS settings
output.logstash:
  hosts: ["local-logstash.internal.local:5044"]
  ssl.supported_protocols: [TLSv1.2, TLSv1.3]
  ssl.verification_mode: full
  ssl.certificate_authorities: ["C:\\ProgramData\\Winlogbeat\\certs\\ca.crt"]
  ssl.certificate: "C:\\ProgramData\\Winlogbeat\\certs\\client.crt"
  ssl.key: "C:\\ProgramData\\Winlogbeat\\certs\\client.key"</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Secure Wazuh Agent Configuration</xhtml:h4>
        <xhtml:p>Edit <xhtml:code>ossec.conf</xhtml:code> (located by default under <xhtml:code>%ProgramFiles(x86)%\ossec-agent\ossec.conf</xhtml:code>) to secure log verification and specify localized channels:</xhtml:p>
        <xhtml:pre>
          <xhtml:code>&lt;ossec_config&gt;
  &lt;client&gt;
    &lt;server&gt;
      &lt;address&gt;local-wazuh.internal.local&lt;/address&gt;
      &lt;port&gt;1514&lt;/port&gt;
      &lt;protocol&gt;tcp&lt;/protocol&gt;
    &lt;/server&gt;
    &lt;crypto_method&gt;aes&lt;/crypto_method&gt;
    &lt;!-- Configure enrollment with validation --&gt;
    &lt;enrollment&gt;
      &lt;enabled&gt;yes&lt;/enabled&gt;
      &lt;server_address&gt;local-wazuh.internal.local&lt;/server_address&gt;
      &lt;port&gt;1515&lt;/port&gt;
      &lt;ssl_cipher&gt;HIGH&lt;/ssl_cipher&gt;
      &lt;ssl_verify_host&gt;yes&lt;/ssl_verify_host&gt;
      &lt;ssl_cacert&gt;C:\Program Files (x86)\ossec-agent\certs\wpk_root.pem&lt;/ssl_cacert&gt;
    &lt;/enrollment&gt;
  &lt;/client&gt;

  &lt;!-- Channels to Monitor --&gt;
  &lt;localfile&gt;
    &lt;location&gt;Security&lt;/location&gt;
    &lt;log_format&gt;eventlog&lt;/log_format&gt;
  &lt;/localfile&gt;
  &lt;localfile&gt;
    &lt;location&gt;System&lt;/location&gt;
    &lt;log_format&gt;eventlog&lt;/log_format&gt;
  &lt;/localfile&gt;
  &lt;localfile&gt;
    &lt;location&gt;Microsoft-Windows-Sysmon/Operational&lt;/location&gt;
    &lt;log_format&gt;eventlog&lt;/log_format&gt;
  &lt;/localfile&gt;
  &lt;localfile&gt;
    &lt;location&gt;Microsoft-Windows-PowerShell/Operational&lt;/location&gt;
    &lt;log_format&gt;eventlog&lt;/log_format&gt;
  &lt;/localfile&gt;
&lt;/ossec_config&gt;</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to secure agent configuration files and verify SIEM shipping services status.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-SiemLogShipping.ps1">Download Script: Set-SiemLogShipping.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-SiemLogShipping.ps1
# Secures Winlogbeat and Wazuh log shipping configuration file ACLs.

Write-Host "--- Hardening SIEM Shipping Agent Configurations ---" -ForegroundColor Cyan

$ConfigFiles = @(
    "C:\Program Files\Winlogbeat\winlogbeat.yml",
    "C:\Program Files (x86)\ossec-agent\ossec.conf"
)

foreach ($File in $ConfigFiles) {
    if (Test-Path $File) {
        Write-Host "[+] Applying hardened NTFS permissions to $($File)..." -ForegroundColor Gray
        
        # Get ACL
        $Acl = Get-Acl -Path $File
        # Disable inheritance and copy existing rules
        $Acl.SetAccessRuleProtection($true, $true)
        Set-Acl -Path $File -AclObject $Acl
        
        # Refresh ACL
        $Acl = Get-Acl -Path $File
        $Rules = $Acl.Access
        
        # Remove any access rules for Users, Authenticated Users, Everyone
        foreach ($Rule in $Rules) {
            $Identity = $Rule.IdentityReference.Value
            if ($Identity -like "*Users" -or $Identity -like "*Authenticated Users" -or $Identity -like "*Everyone") {
                $Acl.RemoveAccessRule($Rule) | Out-Null
            }
        }
        
        # Explicitly ensure Administrators and SYSTEM have Full Control
        $FullRights = [System.Security.AccessControl.FileSystemRights]::FullControl
        $InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
        $AccessType = [System.Security.AccessControl.AccessControlType]::Allow
        
        $AdminRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", $FullRights, $InheritanceFlags, $PropagationFlags, $AccessType)
        $SystemRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", $FullRights, $InheritanceFlags, $PropagationFlags, $AccessType)
        
        $Acl.AddAccessRule($AdminRule)
        $Acl.AddAccessRule($SystemRule)
        
        Set-Acl -Path $File -AclObject $Acl
        Write-Host "    Permissions successfully secured for $($File)." -ForegroundColor Green
    } else {
        Write-Verbose "    File $($File) not found, skipping."
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-SiemLogShipping.ps1">Download Script: Test-SiemLogShipping.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-SiemLogShipping.ps1
# Audits SIEM shipping agents, configuration permissions, and security.

Write-Host "--- Auditing SIEM Log Shipping Agents ---" -ForegroundColor Cyan

# 1. Audit Agent Services
$Services = @("winlogbeat", "WazuhSvc")
foreach ($SvcName in $Services) {
    $Svc = Get-Service -Name $SvcName -ErrorAction SilentlyContinue
    $Status = "Not Installed"
    if ($Svc) {
        $Status = $Svc.Status
    }
    $Color = if ($Status -eq "Running") { "Green" } else { "Yellow" }
    Write-Host "    - Agent Service '$($SvcName)': $($Status)" -ForegroundColor $Color
}

# 2. Audit Config File Access Permissions
$ConfigFiles = @(
    "C:\Program Files\Winlogbeat\winlogbeat.yml",
    "C:\Program Files (x86)\ossec-agent\ossec.conf"
)

foreach ($File in $ConfigFiles) {
    if (Test-Path $File) {
        $Acl = Get-Acl -Path $File
        $Rules = $Acl.Access
        $HasUnsafeAccess = $false
        
        foreach ($Rule in $Rules) {
            $Identity = $Rule.IdentityReference.Value
            $Type = $Rule.AccessControlType
            
            # Verify if users, authenticated users, or everyone has read/write
            if ($Type -eq "Allow" -and ($Identity -like "*Users" -or $Identity -like "*Authenticated Users" -or $Identity -like "*Everyone")) {
                $HasUnsafeAccess = $true
            }
        }
        
        $FileColor = if (-not $HasUnsafeAccess) { "Green" } else { "Red" }
        Write-Host "    - Configuration File: $($File) | UnsafeAccessAllowed=$($HasUnsafeAccess)" -ForegroundColor $FileColor
    } else {
        Write-Host "    - Configuration File: $($File) | Status: NOT FOUND" -ForegroundColor Yellow
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-SiemLogShipping.ps1
# Secures Winlogbeat and Wazuh log shipping configuration file ACLs.

Write-Host "--- Hardening SIEM Shipping Agent Configurations ---" -ForegroundColor Cyan

$ConfigFiles = @(
    "C:\Program Files\Winlogbeat\winlogbeat.yml",
    "C:\Program Files (x86)\ossec-agent\ossec.conf"
)

foreach ($File in $ConfigFiles) {
    if (Test-Path $File) {
        Write-Host "[+] Applying hardened NTFS permissions to $($File)..." -ForegroundColor Gray
        
        # Get ACL
        $Acl = Get-Acl -Path $File
        # Disable inheritance and copy existing rules
        $Acl.SetAccessRuleProtection($true, $true)
        Set-Acl -Path $File -AclObject $Acl
        
        # Refresh ACL
        $Acl = Get-Acl -Path $File
        $Rules = $Acl.Access
        
        # Remove any access rules for Users, Authenticated Users, Everyone
        foreach ($Rule in $Rules) {
            $Identity = $Rule.IdentityReference.Value
            if ($Identity -like "*Users" -or $Identity -like "*Authenticated Users" -or $Identity -like "*Everyone") {
                $Acl.RemoveAccessRule($Rule) | Out-Null
            }
        }
        
        # Explicitly ensure Administrators and SYSTEM have Full Control
        $FullRights = [System.Security.AccessControl.FileSystemRights]::FullControl
        $InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
        $AccessType = [System.Security.AccessControl.AccessControlType]::Allow
        
        $AdminRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", $FullRights, $InheritanceFlags, $PropagationFlags, $AccessType)
        $SystemRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", $FullRights, $InheritanceFlags, $PropagationFlags, $AccessType)
        
        $Acl.AddAccessRule($AdminRule)
        $Acl.AddAccessRule($SystemRule)
        
        Set-Acl -Path $File -AclObject $Acl
        Write-Host "    Permissions successfully secured for $($File)." -ForegroundColor Green
    } else {
        Write-Verbose "    File $($File) not found, skipping."
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-005" severity="medium" weight="10.0" selected="false">
      <title>[REQ-LOG-005] Configure Kerberoasting Honeypots and SIEM Detection Rules</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/implement-kerberoasting-honeypot.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kerberoasting allows an authenticated user to request a Kerberos service ticket (TGS) for any service account mapped to a Service Principal Name (SPN). Because the ticket is encrypted using the service account's password hash, the attacker can extract the encrypted ticket from memory and attempt to crack the password offline using brute-force dictionaries or GPU arrays.</xhtml:p>
        <xhtml:p>To mitigate and detect this vector, two strategies must be implemented:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Service Account Honeypots (Decoy Accounts)</xhtml:strong>:</xhtml:li>
          <xhtml:li>By creating a fake Active Directory user account and registering a decoy SPN on it, security teams establish a high-fidelity trap. Since this decoy account is not tied to any legitimate application or service, no standard user or system has any reason to request a Kerberos ticket for it.</xhtml:li>
          <xhtml:li>- Set the <xhtml:code>adminCount</xhtml:code> attribute to <xhtml:code>1</xhtml:code> so the account appears in attacker search queries searching for high-privilege targets (e.g., Domain Admins).</xhtml:li>
          <xhtml:li>- Any ticket request (Event ID 4769) for the decoy SPN is a definitive indicator of a Kerberoasting attempt, providing a zero-false-positive alert with the attacker's client IP.</xhtml:li>
        </xhtml:ol>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>SIEM Filtering and Correlation</xhtml:strong>:</xhtml:li>
          <xhtml:li>Standard Event ID 4769 logging generates millions of events daily. Filtering this telemetry down to anomalous behavior is necessary to catch broad Kerberoasting scans:</xhtml:li>
          <xhtml:li>- <xhtml:strong>Ticket Encryption Type</xhtml:strong>: Focus on encryption type <xhtml:code>0x17</xhtml:code> (RC4-HMAC-MD5) or legacy DES (<xhtml:code>0x1</xhtml:code>, <xhtml:code>0x2</xhtml:code>, <xhtml:code>0x3</xhtml:code>) as modern Windows environments negotiate AES (<xhtml:code>0x11</xhtml:code> or <xhtml:code>0x12</xhtml:code>) by default.</xhtml:li>
          <xhtml:li>- <xhtml:strong>Account Exclusions</xhtml:strong>: Filter out usernames ending with <xhtml:code>$</xhtml:code> (which represent computer accounts, trusts, or managed service accounts that feature automatically rotated, high-entropy passwords).</xhtml:li>
          <xhtml:li>- <xhtml:strong>Anomalous Patterns</xhtml:strong>: Trigger alerts when a single user account requests RC4 or DES tickets for multiple distinct SPNs within a short timeframe (e.g., less than 5 seconds).</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Users and Computers (GUI)</xhtml:h3>
        <xhtml:h4>1. Create the Decoy Account</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller or administrative workstation with Domain Admin privileges.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create a new User Object (e.g., named <xhtml:code>krbtgt_honey</xhtml:code>).</xhtml:li>
          <xhtml:li>Set a strong, complex 120-character password.</xhtml:li>
          <xhtml:li>In the account options:</xhtml:li>
          <xhtml:li>- Ensure <xhtml:strong>Account is enabled</xhtml:strong> is checked.</xhtml:li>
          <xhtml:li>- Check <xhtml:strong>Password never expires</xhtml:strong>.</xhtml:li>
          <xhtml:li>Open the user properties and navigate to the <xhtml:strong>Account</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>- Click <xhtml:strong>Log On To...</xhtml:strong> under Logon Workstations.</xhtml:li>
          <xhtml:li>- Select <xhtml:strong>The following computers</xhtml:strong> and enter a non-existent hostname (e.g., <xhtml:code>HONEYPOT-VOID-HOST</xhtml:code>).</xhtml:li>
          <xhtml:li>- Click <xhtml:strong>Add</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure administrative attributes</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In Active Directory Users and Computers, select <xhtml:strong>View</xhtml:strong> -&gt; <xhtml:strong>Advanced Features</xhtml:strong> to enable the Attribute Editor.</xhtml:li>
          <xhtml:li>Open the properties of the decoy account and navigate to the <xhtml:strong>Attribute Editor</xhtml:strong> tab.</xhtml:li>
          <xhtml:li>Locate the <xhtml:code>adminCount</xhtml:code> attribute and double-click it.</xhtml:li>
          <xhtml:li>Set the value to <xhtml:code>1</xhtml:code> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Register the Decoy SPN</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open an elevated command prompt on the Domain Controller.</xhtml:li>
          <xhtml:li>Register a unique fake SPN using the <xhtml:code>setspn</xhtml:code> tool:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>setspn -s MSSQLSvc/sql-backup-prod.domain.local:1433 krbtgt_honey</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Active Directory cmdlets</xhtml:h3>
        <xhtml:p>Use this method to automatically deploy the honeypot configuration and audit its compliance status.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/New-KerberoastHoneypot.ps1">Download Script: New-KerberoastHoneypot.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># New-KerberoastHoneypot.ps1
# Description: Configures a decoy Kerberoasting Honeypot account with a fake SPN, AdminCount=1, and restricted logon capabilities.
# Target Engine: Windows PowerShell 5.1

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
param()

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Configure Kerberoasting Honeypot..." -ForegroundColor Cyan

$HoneypotName = "krbtgt_honey"
$HoneypotSPN = "MSSQLSvc/sql-backup-prod.domain.local:1433"
$HoneypotDescription = "Decoy service account for backup database monitoring."

# 1. Check if the honeypot user account already exists
$ExistingUser = Get-ADUser -Filter "SamAccountName -eq '$HoneypotName'"

if (-not $ExistingUser) {
    # Generate a complex 120-character password to prevent cracking
    $Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&amp;*()-_=+"
    $RandomPassword = ""
    for ($i = 0; $i -lt 120; $i++) {
        $Index = Get-Random -Minimum 0 -Maximum $Characters.Length
        $RandomPassword += $Characters[$Index]
    }
    
    $SecurePassword = ConvertTo-SecureString $RandomPassword -AsPlainText -Force

    # Create the AD User.
    # Set LogonWorkstations to a non-existent host to prevent logon attempts.
    # UPN domain suffix should match the root domain.
    $Domain = Get-ADDomain
    New-ADUser -Name $HoneypotName `
               -SamAccountName $HoneypotName `
               -UserPrincipalName "$HoneypotName@$($Domain.DNSRoot)" `
               -AccountPassword $SecurePassword `
               -Enabled $true `
               -Description $HoneypotDescription `
               -LogonWorkstations "HONEYPOT-VOID-HOST" `
               -PasswordNeverExpires $true

    Write-Host "[+] Decoy user account '$HoneypotName' created with logon restrictions." -ForegroundColor Green
} else {
    Write-Host "[*] Decoy user account '$HoneypotName' already exists." -ForegroundColor Yellow
}

# 2. Configure target attributes: AdminCount, ServicePrincipalName
$UserObj = Get-ADUser -Identity $HoneypotName -Properties servicePrincipalName, adminCount

# Set AdminCount to 1 (highly attractive to scanners)
if ($UserObj.adminCount -ne 1) {
    Set-ADUser -Identity $HoneypotName -Replace @{adminCount = 1}
    Write-Host "[+] Set AdminCount to 1 on '$HoneypotName'." -ForegroundColor Green
} else {
    Write-Host "[*] AdminCount is already set to 1." -ForegroundColor Yellow
}

# Set Service Principal Name
$SPNExists = $UserObj.servicePrincipalName | Where-Object { $_ -eq $HoneypotSPN }
if (-not $SPNExists) {
    Set-ADUser -Identity $HoneypotName -Add @{servicePrincipalName = $HoneypotSPN}
    Write-Host "[+] Service Principal Name '$HoneypotSPN' registered on '$HoneypotName'." -ForegroundColor Green
} else {
    Write-Host "[*] Service Principal Name '$HoneypotSPN' already registered." -ForegroundColor Yellow
}

Write-Host "Honeypot configuration applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the honeypot configuration state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-KerberoastHoneypotStatus.ps1">Download Script: Get-KerberoastHoneypotStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KerberoastHoneypotStatus.ps1
# Description: Audits the existence, SPN, AdminCount, and logon restrictions of the Kerberoasting honeypot account.
# Target Engine: Windows PowerShell 5.1

Import-Module ActiveDirectory

Write-Host "--- Auditing Kerberoasting Honeypot Configuration ---" -ForegroundColor Cyan

$HoneypotName = "krbtgt_honey"
$HoneypotSPN = "MSSQLSvc/sql-backup-prod.domain.local:1433"

# 1. Retrieve the honeypot account
$User = Get-ADUser -Filter "SamAccountName -eq '$HoneypotName'" -Properties servicePrincipalName, adminCount, LogonWorkstations

if (-not $User) {
    Write-Host "[-] Decoy user account '$HoneypotName' does not exist." -ForegroundColor Red
    exit 1
}

$IsCompliant = $true

# 2. Verify SPN is registered
$SPNExists = $User.servicePrincipalName | Where-Object { $_ -eq $HoneypotSPN }
if ($SPNExists) {
    Write-Host "[+] Decoy SPN '$HoneypotSPN' is registered on '$HoneypotName'." -ForegroundColor Green
} else {
    Write-Host "[!] Decoy SPN '$HoneypotSPN' is NOT registered on '$HoneypotName'." -ForegroundColor Red
    $IsCompliant = $false
}

# 3. Verify AdminCount is set to 1
if ($User.adminCount -eq 1) {
    Write-Host "[+] AdminCount is set to 1 (deceptive marker active)." -ForegroundColor Green
} else {
    Write-Host "[!] AdminCount is NOT set to 1 on '$HoneypotName'." -ForegroundColor Red
    $IsCompliant = $false
}

# 4. Verify LogonWorkstations restriction
if ($User.LogonWorkstations -like "*HONEYPOT-VOID-HOST*") {
    Write-Host "[+] Logon restrictions enforced (LogonWorkstations contains 'HONEYPOT-VOID-HOST')." -ForegroundColor Green
} else {
    Write-Host "[!] Logon restrictions NOT enforced on '$HoneypotName' (LogonWorkstations: '$($User.LogonWorkstations)')." -ForegroundColor Red
    $IsCompliant = $false
}

if ($IsCompliant) {
    Write-Host "[+] Secure: Kerberoasting Honeypot is fully configured and active." -ForegroundColor Green
    exit 0
} else {
    Write-Host "[-] Non-Compliant: Kerberoasting Honeypot configurations are incomplete." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># New-KerberoastHoneypot.ps1
# Description: Configures a decoy Kerberoasting Honeypot account with a fake SPN, AdminCount=1, and restricted logon capabilities.
# Target Engine: Windows PowerShell 5.1

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
param()

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Configure Kerberoasting Honeypot..." -ForegroundColor Cyan

$HoneypotName = "krbtgt_honey"
$HoneypotSPN = "MSSQLSvc/sql-backup-prod.domain.local:1433"
$HoneypotDescription = "Decoy service account for backup database monitoring."

# 1. Check if the honeypot user account already exists
$ExistingUser = Get-ADUser -Filter "SamAccountName -eq '$HoneypotName'"

if (-not $ExistingUser) {
    # Generate a complex 120-character password to prevent cracking
    $Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&amp;*()-_=+"
    $RandomPassword = ""
    for ($i = 0; $i -lt 120; $i++) {
        $Index = Get-Random -Minimum 0 -Maximum $Characters.Length
        $RandomPassword += $Characters[$Index]
    }
    
    $SecurePassword = ConvertTo-SecureString $RandomPassword -AsPlainText -Force

    # Create the AD User.
    # Set LogonWorkstations to a non-existent host to prevent logon attempts.
    # UPN domain suffix should match the root domain.
    $Domain = Get-ADDomain
    New-ADUser -Name $HoneypotName `
               -SamAccountName $HoneypotName `
               -UserPrincipalName "$HoneypotName@$($Domain.DNSRoot)" `
               -AccountPassword $SecurePassword `
               -Enabled $true `
               -Description $HoneypotDescription `
               -LogonWorkstations "HONEYPOT-VOID-HOST" `
               -PasswordNeverExpires $true

    Write-Host "[+] Decoy user account '$HoneypotName' created with logon restrictions." -ForegroundColor Green
} else {
    Write-Host "[*] Decoy user account '$HoneypotName' already exists." -ForegroundColor Yellow
}

# 2. Configure target attributes: AdminCount, ServicePrincipalName
$UserObj = Get-ADUser -Identity $HoneypotName -Properties servicePrincipalName, adminCount

# Set AdminCount to 1 (highly attractive to scanners)
if ($UserObj.adminCount -ne 1) {
    Set-ADUser -Identity $HoneypotName -Replace @{adminCount = 1}
    Write-Host "[+] Set AdminCount to 1 on '$HoneypotName'." -ForegroundColor Green
} else {
    Write-Host "[*] AdminCount is already set to 1." -ForegroundColor Yellow
}

# Set Service Principal Name
$SPNExists = $UserObj.servicePrincipalName | Where-Object { $_ -eq $HoneypotSPN }
if (-not $SPNExists) {
    Set-ADUser -Identity $HoneypotName -Add @{servicePrincipalName = $HoneypotSPN}
    Write-Host "[+] Service Principal Name '$HoneypotSPN' registered on '$HoneypotName'." -ForegroundColor Green
} else {
    Write-Host "[*] Service Principal Name '$HoneypotSPN' already registered." -ForegroundColor Yellow
}

Write-Host "Honeypot configuration applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-LOG-006" severity="medium" weight="10.0" selected="false">
      <title>[REQ-LOG-006] Configure SYSVOL Decoy XML Honeypot</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>05-logging-monitoring/implement-sysvol-honeypot.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Adversaries seeking to elevate privileges within an Active Directory domain frequently scan the <xhtml:code>SYSVOL</xhtml:code> share for files containing legacy Group Policy Preference (GPP) credentials (specifically searching for the <xhtml:code>cpassword</xhtml:code> attribute in XML files) or startup/login scripts. This discovery scanning is often automated using script search commands (e.g., <xhtml:code>findstr /S cpassword</xhtml:code>) or administrative diagnostic frameworks (such as PowerSploit or BloodHound).</xhtml:p>
        <xhtml:p>To detect these unauthorized discovery scans, security teams can deploy a <xhtml:strong>SYSVOL Decoy XML Honeypot</xhtml:strong>. This decoy consists of a mock Group Policy folder structure containing a dummy GPP <xhtml:code>Groups.xml</xhtml:code> file with fake credential properties.</xhtml:p>
        <xhtml:p>Because this mock policy is not linked to any active Active Directory object, no legitimate system or user account has any reason to query or read this file.</xhtml:p>
        <xhtml:p>By applying an explicit <xhtml:strong>NTFS Deny Read</xhtml:strong> rule to the <xhtml:code>Everyone</xhtml:code> group on the decoy file, any attempt by an attacker to scan or read it will immediately fail and generate a high-fidelity <xhtml:strong>Access Denied</xhtml:strong> event. By configuring file failure auditing on the decoy path, Windows generates <xhtml:strong>Event ID 4656</xhtml:strong> or <xhtml:strong>4663</xhtml:strong> in the Domain Controller's Security Log. These events capture the attacker's account details and client IP address, providing a low-noise, high-fidelity alert.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Domain Controllers File Explorer (GUI)</xhtml:h3>
        <xhtml:p>To manually configure the decoy file: 1. Log on to a Domain Controller with Domain Admin privileges. 2. Navigate to the local SYSVOL policies directory (typically <xhtml:code>C:\Windows\SYSVOL\sysvol\&lt;domain.local&gt;\Policies</xhtml:code>). 3. Create a new folder with a randomly generated GUID format (e.g., <xhtml:code>{5B7853A8-1E74-4C56-AC89-E911A34D2E5B}</xhtml:code>). 4. Inside this folder, create the directory structure: <xhtml:code>Machine\Preferences\Groups</xhtml:code>. 5. Create a new file named <xhtml:code>Groups.xml</xhtml:code> inside <xhtml:code>Groups</xhtml:code> with standard XML structure and a dummy <xhtml:code>cpassword</xhtml:code> attribute: <xhtml:code />
          <xhtml:code>xml &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;Groups clsid="{312F64FA-EB90-4b2e-A6AE-E8C1FCDD4A2C}"&gt; &lt;User clsid="{15C200C5-AE9F-4a18-A372-FD51206104C1}" name="BuiltinAdminDecoy" image="0" changed="2026-07-02 20:56:00" uid="{B6396E70-2EA1-46B4-9F6D-E5D3AD3CD2BE}"&gt; &lt;Properties action="U" newName="LocalAdministrator" changeLogon="0" noChange="1" neverExpires="1" disabled="0" cpassword="j1Uyj/k7S8248c8j838jjSjjSj2jJ29" description="Decoy local admin account for automation services"/&gt; &lt;/User&gt; &lt;/Groups&gt; </xhtml:code>
          <xhtml:code /> 6. Configure the permissions to deny read access: - Right-click <xhtml:code>Groups.xml</xhtml:code> and select <xhtml:strong>Properties</xhtml:strong>. - Navigate to the <xhtml:strong>Security</xhtml:strong> tab and click <xhtml:strong>Advanced</xhtml:strong>. - Click <xhtml:strong>Add</xhtml:strong>. Set the Principal to <xhtml:code>Everyone</xhtml:code>. Set the Type to <xhtml:code>Deny</xhtml:code>. Check the permissions for <xhtml:code>Read &amp; execute</xhtml:code> and <xhtml:code>Read</xhtml:code>. Click <xhtml:strong>OK</xhtml:strong>. 7. Configure File System Auditing on the decoy: - In the <xhtml:strong>Advanced Security Settings</xhtml:strong> window for <xhtml:code>Groups.xml</xhtml:code>, navigate to the <xhtml:strong>Auditing</xhtml:strong> tab. - Click <xhtml:strong>Add</xhtml:strong>. Set the Principal to <xhtml:code>Everyone</xhtml:code>. Set the Type to <xhtml:code>Fail</xhtml:code>. Check the permissions for <xhtml:code>Read &amp; execute</xhtml:code> and <xhtml:code>Read</xhtml:code>. Click <xhtml:strong>OK</xhtml:strong>. - Click <xhtml:strong>Apply</xhtml:strong> and then <xhtml:strong>OK</xhtml:strong>.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Remediation (Non-GPO / Script-based)</xhtml:h3>
        <xhtml:p>Use these scripts to deploy and audit the SYSVOL honeypot.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/New-SYSVOLHoneypot.ps1">Download Script: New-SYSVOLHoneypot.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># New-SYSVOLHoneypot.ps1
# Description: Configures a decoy Group Policy Preferences XML file in SYSVOL with Everyone:Deny read permissions and file access failure auditing.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying hardening requirement: Configure SYSVOL Decoy XML Honeypot..." -ForegroundColor Cyan

# 1. Retrieve local SYSVOL path
$SysvolReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "Sysvol" -ErrorAction SilentlyContinue
if (-not $SysvolReg) {
    Write-Host "[*] SYSVOL registry path not found. Checking standard share path..." -ForegroundColor Yellow
    $SysvolPath = "C:\Windows\SYSVOL\sysvol"
} else {
    $SysvolPath = $SysvolReg.Sysvol
}

if (-not (Test-Path -Path $SysvolPath)) {
    Write-Host "[-] SYSVOL folder not found at path: $SysvolPath. Honeypot cannot be deployed." -ForegroundColor Red
    exit 1
}

# Resolve the active Policies folder path
$PoliciesPath = Get-ChildItem -Path $SysvolPath -Directory | ForEach-Object {
    Join-Path $_.FullName "Policies"
} | Where-Object { Test-Path $_ } | Select-Object -First 1

if (-not $PoliciesPath) {
    Write-Host "[-] GPO Policies folder not found under SYSVOL: $SysvolPath" -ForegroundColor Red
    exit 1
}

# 2. Check if a decoy is already registered
$RegPath = "HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot"
$ExistingGuid = $null
$ExistingPath = $null

if (Test-Path $RegPath) {
    $ExistingGuid = (Get-ItemProperty -Path $RegPath -Name "DecoyGuid" -ErrorAction SilentlyContinue).DecoyGuid
    $ExistingPath = (Get-ItemProperty -Path $RegPath -Name "DecoyPath" -ErrorAction SilentlyContinue).DecoyPath
}

# If it exists, verify it
$DeployNew = $true
if ($ExistingGuid -and $ExistingPath -and (Test-Path $ExistingPath)) {
    Write-Host "[*] Decoy GPO already registered in registry with GUID: $ExistingGuid" -ForegroundColor Yellow
    $DeployNew = $false
}

if ($DeployNew) {
    # Generate a new random GUID
    $Guid = [guid]::NewGuid().ToString("B").ToUpper()
    $DecoyGpoPath = Join-Path $PoliciesPath $Guid
    $DecoyGroupsPath = Join-Path $DecoyGpoPath "Machine\Preferences\Groups"
    $DecoyXmlPath = Join-Path $DecoyGroupsPath "Groups.xml"

    Write-Host "[*] Deploying new decoy GPO folder at: $DecoyGpoPath" -ForegroundColor White
    New-Item -ItemType Directory -Path $DecoyGroupsPath -Force | Out-Null

    # Create dummy XML file with decoy cpassword content
    $DecoyXmlContent = @'
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;Groups clsid="{312F64FA-EB90-4b2e-A6AE-E8C1FCDD4A2C}"&gt;
  &lt;User clsid="{15C200C5-AE9F-4a18-A372-FD51206104C1}" name="BuiltinAdminDecoy" image="0" changed="2026-07-02 20:56:00" uid="{B6396E70-2EA1-46B4-9F6D-E5D3AD3CD2BE}"&gt;
    &lt;Properties action="U" newName="LocalAdministrator" changeLogon="0" noChange="1" neverExpires="1" disabled="0" cpassword="j1Uyj/k7S8248c8j838jjSjjSj2jJ29" description="Decoy local admin account for automation services"/&gt;
  &lt;/User&gt;
&lt;/Groups&gt;
'@
    Set-Content -Path $DecoyXmlPath -Value $DecoyXmlContent -Force | Out-Null
    Write-Host "[+] Decoy GPP Groups.xml created." -ForegroundColor Green

    # Save to Registry
    if (-not (Test-Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
    }
    Set-ItemProperty -Path $RegPath -Name "DecoyGuid" -Value $Guid -Type String
    Set-ItemProperty -Path $RegPath -Name "DecoyPath" -Value $DecoyXmlPath -Type String
    Write-Host "[+] Registered Decoy Guid: $Guid in HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot" -ForegroundColor Gray
} else {
    $DecoyXmlPath = $ExistingPath
}

# 3. Configure permissions: Deny Everyone Read access
Write-Host "[*] Enforcing Deny Read/Execute permissions for Everyone on decoy file..." -ForegroundColor White
$Acl = Get-Acl -Path $DecoyXmlPath

# Check if Deny rule for Everyone already exists to avoid duplication
$HasDenyRule = $false
foreach ($rule in $Acl.GetAccessRules($true, $false, [System.Security.Principal.NTAccount])) {
    if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny) {
        $HasDenyRule = $true
        break
    }
}

if (-not $HasDenyRule) {
    $Identity = "Everyone"
    $Rights = [System.Security.AccessControl.FileSystemRights]::ReadAndExecute -bor [System.Security.AccessControl.FileSystemRights]::Read
    $Inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $Propagation = [System.Security.AccessControl.PropagationFlags]::None
    $Type = [System.Security.AccessControl.AccessControlType]::Deny

    $DenyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Identity, $Rights, $Inheritance, $Propagation, $Type)
    $Acl.AddAccessRule($DenyRule)
    Set-Acl -Path $DecoyXmlPath -AclObject $Acl
    Write-Host "[+] Applied Deny Everyone rule successfully." -ForegroundColor Green
} else {
    Write-Host "[*] Deny Everyone rule is already present." -ForegroundColor Yellow
}

# 4. Configure Object Auditing for Failure (SACL)
Write-Host "[*] Configuring Failure Audit rule for Everyone on decoy file..." -ForegroundColor White

# To set SACL, we must load the ACL with audit rules
$AclAudit = Get-Acl -Path $DecoyXmlPath -Audit

$HasAuditRule = $false
foreach ($rule in $AclAudit.GetAuditRules($true, $false, [System.Security.Principal.NTAccount])) {
    if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AuditFlags -eq [System.Security.AccessControl.AuditFlags]::Failure) {
        $HasAuditRule = $true
        break
    }
}

if (-not $HasAuditRule) {
    $AuditIdentity = "Everyone"
    $AuditRights = [System.Security.AccessControl.FileSystemRights]::ReadAndExecute -bor [System.Security.AccessControl.FileSystemRights]::Read
    $AuditInheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $AuditPropagation = [System.Security.AccessControl.PropagationFlags]::None
    $AuditFlags = [System.Security.AccessControl.AuditFlags]::Failure

    $AuditRule = New-Object System.Security.AccessControl.FileSystemAuditRule($AuditIdentity, $AuditRights, $AuditInheritance, $AuditPropagation, $AuditFlags)
    $AclAudit.AddAuditRule($AuditRule)
    
    # Set the ACL with audit rules back to the file
    Set-Acl -Path $DecoyXmlPath -AclObject $AclAudit
    Write-Host "[+] Applied Failure Audit rule successfully." -ForegroundColor Green
} else {
    Write-Host "[*] Failure Audit rule is already present." -ForegroundColor Yellow
}

Write-Host "SYSVOL Decoy XML Honeypot configuration completed successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the honeypot configuration status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SYSVOLHoneypotStatus.ps1">Download Script: Get-SYSVOLHoneypotStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SYSVOLHoneypotStatus.ps1
# Description: Checks the configuration status of the SYSVOL Decoy XML Honeypot.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing SYSVOL Decoy XML Honeypot Configuration ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$RegPath = "HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot"

if (Test-Path $RegPath) {
    $DecoyGuid = (Get-ItemProperty -Path $RegPath -Name "DecoyGuid" -ErrorAction SilentlyContinue).DecoyGuid
    $DecoyPath = (Get-ItemProperty -Path $RegPath -Name "DecoyPath" -ErrorAction SilentlyContinue).DecoyPath
    
    if (-not $DecoyGuid) {
        Write-Host "[-] Decoy GPO GUID is missing in the registry." -ForegroundColor Red
        $script:Vulnerable = $true
    }
    
    if (-not $DecoyPath) {
        Write-Host "[-] Decoy file path is missing in the registry." -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        if (-not (Test-Path $DecoyPath)) {
            Write-Host "[-] Decoy XML file does not exist at registered path: $DecoyPath" -ForegroundColor Red
            $script:Vulnerable = $true
        } else {
            Write-Host "[+] Decoy XML file found: $DecoyPath" -ForegroundColor Green
            
            # Check Deny ACL rule
            $Acl = Get-Acl -Path $DecoyPath
            $HasDenyRule = $false
            foreach ($rule in $Acl.GetAccessRules($true, $false, [System.Security.Principal.NTAccount])) {
                if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny) {
                    $HasDenyRule = $true
                    break
                }
            }
            
            if ($HasDenyRule) {
                Write-Host "    - Everyone Deny Read rule: CONFIGURED" -ForegroundColor White
            } else {
                Write-Host "    - Everyone Deny Read rule: NOT CONFIGURED" -ForegroundColor Red
                $script:Vulnerable = $true
            }
            
            # Check Audit failure rule (SACL)
            $AclAudit = Get-Acl -Path $DecoyPath -Audit
            $HasAuditRule = $false
            foreach ($rule in $AclAudit.GetAuditRules($true, $false, [System.Security.Principal.NTAccount])) {
                if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AuditFlags -eq [System.Security.AccessControl.AuditFlags]::Failure) {
                    $HasAuditRule = $true
                    break
                }
            }
            
            if ($HasAuditRule) {
                Write-Host "    - Everyone Failure Audit rule: CONFIGURED" -ForegroundColor White
            } else {
                Write-Host "    - Everyone Failure Audit rule: NOT CONFIGURED" -ForegroundColor Red
                $script:Vulnerable = $true
            }
        }
    }
} else {
    Write-Host "[-] Decoy registry key not found under HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># New-SYSVOLHoneypot.ps1
# Description: Configures a decoy Group Policy Preferences XML file in SYSVOL with Everyone:Deny read permissions and file access failure auditing.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying hardening requirement: Configure SYSVOL Decoy XML Honeypot..." -ForegroundColor Cyan

# 1. Retrieve local SYSVOL path
$SysvolReg = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "Sysvol" -ErrorAction SilentlyContinue
if (-not $SysvolReg) {
    Write-Host "[*] SYSVOL registry path not found. Checking standard share path..." -ForegroundColor Yellow
    $SysvolPath = "C:\Windows\SYSVOL\sysvol"
} else {
    $SysvolPath = $SysvolReg.Sysvol
}

if (-not (Test-Path -Path $SysvolPath)) {
    Write-Host "[-] SYSVOL folder not found at path: $SysvolPath. Honeypot cannot be deployed." -ForegroundColor Red
    exit 1
}

# Resolve the active Policies folder path
$PoliciesPath = Get-ChildItem -Path $SysvolPath -Directory | ForEach-Object {
    Join-Path $_.FullName "Policies"
} | Where-Object { Test-Path $_ } | Select-Object -First 1

if (-not $PoliciesPath) {
    Write-Host "[-] GPO Policies folder not found under SYSVOL: $SysvolPath" -ForegroundColor Red
    exit 1
}

# 2. Check if a decoy is already registered
$RegPath = "HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot"
$ExistingGuid = $null
$ExistingPath = $null

if (Test-Path $RegPath) {
    $ExistingGuid = (Get-ItemProperty -Path $RegPath -Name "DecoyGuid" -ErrorAction SilentlyContinue).DecoyGuid
    $ExistingPath = (Get-ItemProperty -Path $RegPath -Name "DecoyPath" -ErrorAction SilentlyContinue).DecoyPath
}

# If it exists, verify it
$DeployNew = $true
if ($ExistingGuid -and $ExistingPath -and (Test-Path $ExistingPath)) {
    Write-Host "[*] Decoy GPO already registered in registry with GUID: $ExistingGuid" -ForegroundColor Yellow
    $DeployNew = $false
}

if ($DeployNew) {
    # Generate a new random GUID
    $Guid = [guid]::NewGuid().ToString("B").ToUpper()
    $DecoyGpoPath = Join-Path $PoliciesPath $Guid
    $DecoyGroupsPath = Join-Path $DecoyGpoPath "Machine\Preferences\Groups"
    $DecoyXmlPath = Join-Path $DecoyGroupsPath "Groups.xml"

    Write-Host "[*] Deploying new decoy GPO folder at: $DecoyGpoPath" -ForegroundColor White
    New-Item -ItemType Directory -Path $DecoyGroupsPath -Force | Out-Null

    # Create dummy XML file with decoy cpassword content
    $DecoyXmlContent = @'
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;Groups clsid="{312F64FA-EB90-4b2e-A6AE-E8C1FCDD4A2C}"&gt;
  &lt;User clsid="{15C200C5-AE9F-4a18-A372-FD51206104C1}" name="BuiltinAdminDecoy" image="0" changed="2026-07-02 20:56:00" uid="{B6396E70-2EA1-46B4-9F6D-E5D3AD3CD2BE}"&gt;
    &lt;Properties action="U" newName="LocalAdministrator" changeLogon="0" noChange="1" neverExpires="1" disabled="0" cpassword="j1Uyj/k7S8248c8j838jjSjjSj2jJ29" description="Decoy local admin account for automation services"/&gt;
  &lt;/User&gt;
&lt;/Groups&gt;
'@
    Set-Content -Path $DecoyXmlPath -Value $DecoyXmlContent -Force | Out-Null
    Write-Host "[+] Decoy GPP Groups.xml created." -ForegroundColor Green

    # Save to Registry
    if (-not (Test-Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
    }
    Set-ItemProperty -Path $RegPath -Name "DecoyGuid" -Value $Guid -Type String
    Set-ItemProperty -Path $RegPath -Name "DecoyPath" -Value $DecoyXmlPath -Type String
    Write-Host "[+] Registered Decoy Guid: $Guid in HKLM:\SOFTWARE\ADHardening\SYSVOLHoneypot" -ForegroundColor Gray
} else {
    $DecoyXmlPath = $ExistingPath
}

# 3. Configure permissions: Deny Everyone Read access
Write-Host "[*] Enforcing Deny Read/Execute permissions for Everyone on decoy file..." -ForegroundColor White
$Acl = Get-Acl -Path $DecoyXmlPath

# Check if Deny rule for Everyone already exists to avoid duplication
$HasDenyRule = $false
foreach ($rule in $Acl.GetAccessRules($true, $false, [System.Security.Principal.NTAccount])) {
    if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny) {
        $HasDenyRule = $true
        break
    }
}

if (-not $HasDenyRule) {
    $Identity = "Everyone"
    $Rights = [System.Security.AccessControl.FileSystemRights]::ReadAndExecute -bor [System.Security.AccessControl.FileSystemRights]::Read
    $Inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $Propagation = [System.Security.AccessControl.PropagationFlags]::None
    $Type = [System.Security.AccessControl.AccessControlType]::Deny

    $DenyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Identity, $Rights, $Inheritance, $Propagation, $Type)
    $Acl.AddAccessRule($DenyRule)
    Set-Acl -Path $DecoyXmlPath -AclObject $Acl
    Write-Host "[+] Applied Deny Everyone rule successfully." -ForegroundColor Green
} else {
    Write-Host "[*] Deny Everyone rule is already present." -ForegroundColor Yellow
}

# 4. Configure Object Auditing for Failure (SACL)
Write-Host "[*] Configuring Failure Audit rule for Everyone on decoy file..." -ForegroundColor White

# To set SACL, we must load the ACL with audit rules
$AclAudit = Get-Acl -Path $DecoyXmlPath -Audit

$HasAuditRule = $false
foreach ($rule in $AclAudit.GetAuditRules($true, $false, [System.Security.Principal.NTAccount])) {
    if ($rule.IdentityReference.Value -eq "Everyone" -and $rule.AuditFlags -eq [System.Security.AccessControl.AuditFlags]::Failure) {
        $HasAuditRule = $true
        break
    }
}

if (-not $HasAuditRule) {
    $AuditIdentity = "Everyone"
    $AuditRights = [System.Security.AccessControl.FileSystemRights]::ReadAndExecute -bor [System.Security.AccessControl.FileSystemRights]::Read
    $AuditInheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $AuditPropagation = [System.Security.AccessControl.PropagationFlags]::None
    $AuditFlags = [System.Security.AccessControl.AuditFlags]::Failure

    $AuditRule = New-Object System.Security.AccessControl.FileSystemAuditRule($AuditIdentity, $AuditRights, $AuditInheritance, $AuditPropagation, $AuditFlags)
    $AclAudit.AddAuditRule($AuditRule)
    
    # Set the ACL with audit rules back to the file
    Set-Acl -Path $DecoyXmlPath -AclObject $AclAudit
    Write-Host "[+] Applied Failure Audit rule successfully." -ForegroundColor Green
} else {
    Write-Host "[*] Failure Audit rule is already present." -ForegroundColor Yellow
}

Write-Host "SYSVOL Decoy XML Honeypot configuration completed successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:5006" />
      </check>
    </Rule>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_6__Secure_Operations___Maintenance">
    <title>Module 6: Secure Operations &amp; Maintenance</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-OPS-001] Enforce KRBTGT Password Rotation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Primary Domain Controller / PDC Emulator, replica Domain Controllers)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Directory Scope</xhtml:strong>: Forest Root Domain, Child Domains, and Read-Only Domain Controllers (RODCs)</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/enforce-krbtgt-password-rotation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The <xhtml:code>krbtgt</xhtml:code> account is a built-in local service account that serves as the Key Distribution Center (KDC) service account in Active Directory. The long-term secret cryptographic keys derived from the <xhtml:code>krbtgt</xhtml:code> account password are used by the KDC to sign and encrypt all Kerberos Ticket Granting Tickets (TGTs) issued within the domain, as well as to compute the Privilege Attribute Certificate (PAC) signatures that vouch for user identity, security identifiers (SIDs), and group memberships.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Baseline &amp; Staged Administrative Procedure</xhtml:h3>
        <xhtml:p>Kerberos ticket lifetimes are governed via Group Policy Objects, while the password rotation itself is an operational database procedure executed against Active Directory objects.</xhtml:p>
        <xhtml:h4>1. Verify and Enforce Domain Kerberos Policy via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the <xhtml:strong>Default Domain Policy</xhtml:strong> (or a dedicated Tier 0 Domain Controller Policy linked at the domain root).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Kerberos Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Verify and enforce standard Kerberos parameters:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce user logon restrictions</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for service ticket</xhtml:em>*: <xhtml:code>600</xhtml:code> minutes (10 hours)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket</xhtml:em>*: <xhtml:code>10</xhtml:code> hours</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket renewal</xhtml:em>*: <xhtml:code>7</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum tolerance for computer clock synchronization</xhtml:em>*: <xhtml:code>5</xhtml:code> minutes</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Staged Administrative Procedure for KRBTGT Rotation</xhtml:h4>
        <xhtml:p>To execute the staged rotation using Active Directory administrative tools:</xhtml:p>
        <xhtml:h5>Phase 1: Pre-Rotation Assessment</xhtml:h5>
        <xhtml:ol>
          <xhtml:li>Identify the Primary Domain Controller (PDC) Emulator for the domain:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>netdom query fsmo</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Verify that Active Directory replication is completely healthy across all Domain Controllers:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>repadmin /replsummary</xhtml:li>
          <xhtml:li>repadmin /showrepl * /csv</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Audit the existing <xhtml:code>krbtgt</xhtml:code> password age and <xhtml:code>kvno</xhtml:code> (using the audit script below).</xhtml:li>
        </xhtml:ol>
        <xhtml:h5>Phase 2: First Password Reset (Step 1)</xhtml:h5>
        <xhtml:ol>
          <xhtml:li>Log on to the <xhtml:strong>PDC Emulator</xhtml:strong> with Domain Admin or Enterprise Admin credentials.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>), ensure <xhtml:strong>View -&gt; Advanced Features</xhtml:strong> is enabled.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Users</xhtml:strong> container, right-click <xhtml:strong>krbtgt</xhtml:strong>, and select <xhtml:strong>Reset Password</xhtml:strong>.</xhtml:li>
          <xhtml:li>Enter a strong, cryptographically complex random password (minimum 128 characters) and confirm it. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Trigger replication across all Domain Controllers:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>repadmin /syncall /AdeP</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h5>Phase 3: Cooldown and Ticket Expiration Window</xhtml:h5>
        <xhtml:ol>
          <xhtml:li>Wait a minimum of <xhtml:strong>10 to 24 hours</xhtml:strong>.</xhtml:li>
          <xhtml:li>Monitor Domain Controller Security Event Logs for Kerberos ticket renewal events (Event ID 4768) and verify replication convergence.</xhtml:li>
        </xhtml:ol>
        <xhtml:h5>Phase 4: Second Password Reset (Step 2)</xhtml:h5>
        <xhtml:ol>
          <xhtml:li>On the PDC Emulator, repeat the password reset procedure on the <xhtml:strong>krbtgt</xhtml:strong> account with a new, distinct 128-character password.</xhtml:li>
          <xhtml:li>Trigger replication across all Domain Controllers:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>repadmin /syncall /AdeP</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h5>Phase 5: Post-Rotation Verification</xhtml:h5>
        <xhtml:ol>
          <xhtml:li>Run the audit script below to verify that all Domain Controllers report the updated <xhtml:code>PasswordLastSet</xhtml:code> and matching <xhtml:code>kvno</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Operational Automation (Remediation / Audit)</xhtml:h3>
        <xhtml:p>Use the following enterprise-grade PowerShell scripts to programmatically manage and audit the KRBTGT password rotation lifecycle.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Reset-KrbtgtPassword.ps1">Download Script: Reset-KrbtgtPassword.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Reset-KrbtgtPassword.ps1
# Description: Resets the KRBTGT account password on the PDC Emulator with a cryptographically secure 128-character password, enforces cooldown safety, and triggers AD replication.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High")]
param (
    [Parameter(Mandatory = $false)]
    [switch]$Force,

    [Parameter(Mandatory = $false)]
    [int]$MinCooldownHours = 10,

    [Parameter(Mandatory = $false)]
    [string]$Server
)

Write-Host "--- Applying Hardening Requirement: KRBTGT Password Rotation ---" -ForegroundColor Cyan

# 1. Verify Active Directory module
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    return
}

Import-Module ActiveDirectory -ErrorAction Stop

# 2. Discover target Domain Controller (PDC Emulator)
try {
    $domain = Get-ADDomain -ErrorAction Stop
    $targetServer = $Server
    if (-not $targetServer) {
        $targetServer = $domain.PDCEmulator
    }
    Write-Host "[*] Target Domain: $($domain.DNSRoot)" -ForegroundColor Gray
    Write-Host "[*] Authoritative PDC Emulator: $targetServer" -ForegroundColor Gray
} catch {
    Write-Error "Failed to locate domain or PDC Emulator: $($_.Exception.Message)"
    return
}

# 3. Retrieve authoritative KRBTGT object
try {
    $krbtgt = Get-ADUser -Identity "krbtgt" -Server $targetServer -Properties PasswordLastSet, Enabled, "msDS-KeyVersionNumber", userAccountControl -ErrorAction Stop
    if (-not $krbtgt) {
        Write-Error "KRBTGT account not found on $targetServer."
        return
    }
} catch {
    Write-Error "Failed to retrieve KRBTGT account from $($targetServer): $($_.Exception.Message)"
    return
}

$lastSet = $krbtgt.PasswordLastSet
$currentKvno = $krbtgt."msDS-KeyVersionNumber"

Write-Host "[*] Current KRBTGT Password Last Set: $lastSet" -ForegroundColor Gray
Write-Host "[*] Current Key Version Number (kvno): $currentKvno" -ForegroundColor Gray

# 4. Enforce Cooldown Safety Check
if ($null -ne $lastSet) {
    $elapsedHours = (New-TimeSpan -Start $lastSet -End (Get-Date)).TotalHours
    if ($elapsedHours -lt $MinCooldownHours -and -not $Force) {
        $roundedHours = [math]::Round($elapsedHours, 1)
        Write-Warning "SAFETY INTERLOCK ENGAGED: The KRBTGT password was last set only $roundedHours hours ago."
        Write-Warning "Resetting KRBTGT again before the Kerberos ticket lifetime ($MinCooldownHours hours) has elapsed"
        Write-Warning "will purge the previous key from history and invalidate ALL active domain TGTs,"
        Write-Warning "causing enterprise-wide authentication failure for all users and services."
        Write-Warning "To override this interlock (e.g., during active incident containment), specify -Force."
        return
    }
}

# 5. Generate Cryptographically Secure 128-Character Password
$length = 128
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&amp;*()_+-=[]{}|;:,.&lt;&gt;?"
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$bytes = New-Object byte[] $length
$rng.GetBytes($bytes)

$securePassword = New-Object System.Security.SecureString
for ($i = 0; $i -lt $length; $i++) {
    $char = $chars[$bytes[$i] % $chars.Length]
    $securePassword.AppendChar($char)
}
$securePassword.MakeReadOnly()
$rng.Dispose()

# 6. Execute Password Reset via ShouldProcess
$confirmTarget = "KRBTGT account on $targetServer (Domain: $($domain.DNSRoot))"
if ($PSCmdlet.ShouldProcess($confirmTarget, "Reset KRBTGT account password and increment kvno")) {
    try {
        Set-ADAccountPassword -Identity $krbtgt -Server $targetServer -NewPassword $securePassword -Reset -ErrorAction Stop
        Write-Host "[+] KRBTGT password successfully reset on PDC Emulator ($targetServer)." -ForegroundColor Green

        # Re-query to verify kvno increment
        Start-Sleep -Seconds 2
        $updatedKrbtgt = Get-ADUser -Identity "krbtgt" -Server $targetServer -Properties PasswordLastSet, "msDS-KeyVersionNumber" -ErrorAction Stop
        Write-Host "[+] New Password Last Set: $($updatedKrbtgt.PasswordLastSet)" -ForegroundColor Green
        Write-Host "[+] New Key Version Number (kvno): $($updatedKrbtgt.'msDS-KeyVersionNumber')" -ForegroundColor Green

        # 7. Dispatch Active Directory Replication
        Write-Host "[*] Triggering Active Directory replication synchronization..." -ForegroundColor Cyan
        $repadmin = Get-Command -Name "repadmin.exe" -ErrorAction SilentlyContinue
        if ($repadmin) {
            &amp; repadmin.exe /syncall /AdeP | Out-Null
            Write-Host "[+] Active Directory replication triggered across all domain partitions." -ForegroundColor Green
        } else {
            try {
                Sync-ADObject -Identity $krbtgt.DistinguishedName -Server $targetServer -ErrorAction SilentlyContinue
                Write-Host "[+] Sync-ADObject invoked for KRBTGT account." -ForegroundColor Green
            } catch {
                Write-Warning "Could not trigger replication automatically. Ensure replication runs across all domain controllers."
            }
        }

        Write-Host ""
        Write-Host "=========================================================================" -ForegroundColor Yellow
        Write-Host "[IMPORTANT] Two-Step KRBTGT Password Rotation Protocol:" -ForegroundColor Yellow
        Write-Host " 1. This reset constitutes Step 1 of the rotation cycle." -ForegroundColor Yellow
        Write-Host " 2. Active Directory retains the previous key in history (index 1) so" -ForegroundColor Yellow
        Write-Host "    existing valid Kerberos tickets continue to function until expiration." -ForegroundColor Yellow
        Write-Host " 3. You MUST WAIT at least $MinCooldownHours to 24 hours for all active tickets" -ForegroundColor Yellow
        Write-Host "    to renew and for replication to converge across all domain controllers." -ForegroundColor Yellow
        Write-Host " 4. After the cooldown period, run this script again to perform Step 2," -ForegroundColor Yellow
        Write-Host "    which purges the pre-rotation key and completely invalidates any" -ForegroundColor Yellow
        Write-Host "    historical Golden, Diamond, or forged Kerberos tickets." -ForegroundColor Yellow
        Write-Host "=========================================================================" -ForegroundColor Yellow
    } catch {
        Write-Error "Failed to reset KRBTGT password: $($_.Exception.Message)"
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the password rotation status and replication convergence of the KRBTGT account:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-KrbtgtRotationStatus.ps1">Download Script: Get-KrbtgtRotationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-KrbtgtRotationStatus.ps1
# Description: Audits KRBTGT password age, kvno, replication convergence across all Domain Controllers, and RODC accounts.
# Target Engine: Windows PowerShell 5.1

Import-Module ActiveDirectory -ErrorAction Stop

Write-Host "--- Auditing KRBTGT Password Rotation Status ---" -ForegroundColor Cyan

# 1. Discover Domain and Authoritative PDC Emulator
try {
    $domain = Get-ADDomain -ErrorAction Stop
    $pdc = $domain.PDCEmulator
    Write-Host "[*] Domain: $($domain.DNSRoot)" -ForegroundColor Gray
    Write-Host "[*] Authoritative PDC Emulator: $pdc" -ForegroundColor Gray
} catch {
    Write-Error "Failed to query domain or PDC Emulator: $($_.Exception.Message)"
    return
}

# 2. Retrieve Kerberos Policy MaxTicketAge
$maxTicketAgeHours = 10
try {
    $kerbPolicy = Get-ADDefaultDomainPasswordPolicy -ErrorAction SilentlyContinue
    if ($kerbPolicy -and $kerbPolicy.MaxTicketAge) {
        $maxTicketAgeHours = [math]::Round($kerbPolicy.MaxTicketAge.TotalHours, 1)
    }
} catch {
    $maxTicketAgeHours = 10
}
Write-Host "[*] Configured Kerberos MaxTicketAge: $maxTicketAgeHours hours" -ForegroundColor Gray

# 3. Query Primary KRBTGT Object on PDC
$krbtgt = Get-ADUser -Identity "krbtgt" -Server $pdc -Properties PasswordLastSet, PasswordExpired, Enabled, "msDS-KeyVersionNumber", "msDS-SupportedEncryptionTypes" -ErrorAction SilentlyContinue

if (-not $krbtgt) {
    Write-Error "KRBTGT account not found in Active Directory."
    return
}

$passwordLastSet = $krbtgt.PasswordLastSet
$kvno = $krbtgt."msDS-KeyVersionNumber"
$encTypes = $krbtgt."msDS-SupportedEncryptionTypes"

Write-Host "    - Account Name: $($krbtgt.Name)" -ForegroundColor White
Write-Host "    - Enabled: $($krbtgt.Enabled)" -ForegroundColor White
Write-Host "    - Key Version Number (kvno): $kvno" -ForegroundColor White
Write-Host "    - Supported Encryption Types Bitmask: $encTypes" -ForegroundColor White

if ($null -ne $passwordLastSet) {
    $ageDays = (New-TimeSpan -Start $passwordLastSet -End (Get-Date)).Days
    $ageHours = (New-TimeSpan -Start $passwordLastSet -End (Get-Date)).TotalHours
    $stigThresholdDays = 180
    $anssiThresholdDays = 90

    Write-Host "    - Password Last Set: $passwordLastSet ($ageDays days ago / $([math]::Round($ageHours, 1)) hours ago)" -ForegroundColor White

    # Check if currently inside the two-step cooldown window
    if ($ageHours -lt $maxTicketAgeHours) {
        Write-Host "    - Cooldown Status: IN-PROGRESS (Step 1 executed $([math]::Round($ageHours, 1)) hours ago; wait until $maxTicketAgeHours hours have elapsed before executing Step 2)." -ForegroundColor Yellow
    }

    # Evaluate compliance thresholds
    if ($ageDays -gt $stigThresholdDays) {
        Write-Host "    - Compliance Status: FAILED - KRBTGT password has not been rotated in $ageDays days (DoD STIG threshold: $stigThresholdDays days)." -ForegroundColor Red
    } elseif ($ageDays -gt $anssiThresholdDays) {
        Write-Host "    - Compliance Status: WARNING - KRBTGT password age is $ageDays days (Exceeds ANSSI recommendation of $anssiThresholdDays days; compliant with STIG threshold of $stigThresholdDays days)." -ForegroundColor Yellow
    } else {
        Write-Host "    - Compliance Status: PASSED - KRBTGT password age is $ageDays days (Compliant with STIG and ANSSI baselines)." -ForegroundColor Green
    }
} else {
    Write-Host "    - Compliance Status: FAILED - PasswordLastSet attribute is null." -ForegroundColor Red
}

# 4. Audit Replication Consistency Across All Reachable DCs
Write-Host "`n[*] Auditing KRBTGT Replication Convergence Across Domain Controllers:" -ForegroundColor Cyan
$dcs = Get-ADDomainController -Filter * -ErrorAction SilentlyContinue
$dcResults = @()
$replicationDiscrepancy = $false

foreach ($dc in $dcs) {
    try {
        $dcKrbtgt = Get-ADUser -Identity "krbtgt" -Server $dc.HostName -Properties PasswordLastSet, "msDS-KeyVersionNumber" -ErrorAction Stop
        $match = ($dcKrbtgt.PasswordLastSet -eq $passwordLastSet) -and ($dcKrbtgt."msDS-KeyVersionNumber" -eq $kvno)
        if (-not $match) {
            $replicationDiscrepancy = $true
        }
        $dcResults += [PSCustomObject]@{
            DomainController = $dc.HostName
            Reachable        = $true
            PasswordLastSet  = $dcKrbtgt.PasswordLastSet
            Kvno             = $dcKrbtgt."msDS-KeyVersionNumber"
            InSync           = $match
        }
    } catch {
        $dcResults += [PSCustomObject]@{
            DomainController = $dc.HostName
            Reachable        = $false
            PasswordLastSet  = $null
            Kvno             = $null
            InSync           = $false
        }
    }
}

foreach ($res in $dcResults) {
    if ($res.Reachable -and $res.InSync) {
        Write-Host "    [OK] $($res.DomainController): kvno=$($res.Kvno), LastSet=$($res.PasswordLastSet)" -ForegroundColor Green
    } elseif ($res.Reachable -and -not $res.InSync) {
        Write-Host "    [MISMATCH] $($res.DomainController): kvno=$($res.Kvno), LastSet=$($res.PasswordLastSet) (Out of sync with PDC)" -ForegroundColor Red
    } else {
        Write-Host "    [UNREACHABLE] $($res.DomainController): Unable to query" -ForegroundColor Yellow
    }
}

if ($replicationDiscrepancy) {
    Write-Host "    [!] Warning: Replication discrepancy detected across Domain Controllers." -ForegroundColor Red
}

# 5. Audit Read-Only Domain Controller (RODC) KRBTGT Accounts
Write-Host "`n[*] Auditing Read-Only Domain Controller (RODC) KRBTGT Accounts:" -ForegroundColor Cyan
$rodcAccounts = Get-ADUser -Filter "Name -like 'krbtgt_*'" -Server $pdc -Properties PasswordLastSet, "msDS-KeyVersionNumber", Enabled -ErrorAction SilentlyContinue

if ($rodcAccounts -and $rodcAccounts.Count -gt 0) {
    Write-Host "    Found $($rodcAccounts.Count) RODC KRBTGT account(s):" -ForegroundColor Gray
    foreach ($rodc in $rodcAccounts) {
        $rodcAgeDays = "N/A"
        if ($rodc.PasswordLastSet) {
            $rodcAgeDays = (New-TimeSpan -Start $rodc.PasswordLastSet -End (Get-Date)).Days
        }
        Write-Host "    - $($rodc.SamAccountName): kvno=$($rodc.'msDS-KeyVersionNumber'), LastSet=$($rodc.PasswordLastSet) ($rodcAgeDays days ago), Enabled=$($rodc.Enabled)" -ForegroundColor White
    }
} else {
    Write-Host "    No Read-Only Domain Controller (RODC) accounts detected in this domain." -ForegroundColor Gray
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Reset-KrbtgtPassword.ps1
# Description: Resets the KRBTGT account password on the PDC Emulator with a cryptographically secure 128-character password, enforces cooldown safety, and triggers AD replication.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High")]
param (
    [Parameter(Mandatory = $false)]
    [switch]$Force,

    [Parameter(Mandatory = $false)]
    [int]$MinCooldownHours = 10,

    [Parameter(Mandatory = $false)]
    [string]$Server
)

Write-Host "--- Applying Hardening Requirement: KRBTGT Password Rotation ---" -ForegroundColor Cyan

# 1. Verify Active Directory module
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    return
}

Import-Module ActiveDirectory -ErrorAction Stop

# 2. Discover target Domain Controller (PDC Emulator)
try {
    $domain = Get-ADDomain -ErrorAction Stop
    $targetServer = $Server
    if (-not $targetServer) {
        $targetServer = $domain.PDCEmulator
    }
    Write-Host "[*] Target Domain: $($domain.DNSRoot)" -ForegroundColor Gray
    Write-Host "[*] Authoritative PDC Emulator: $targetServer" -ForegroundColor Gray
} catch {
    Write-Error "Failed to locate domain or PDC Emulator: $($_.Exception.Message)"
    return
}

# 3. Retrieve authoritative KRBTGT object
try {
    $krbtgt = Get-ADUser -Identity "krbtgt" -Server $targetServer -Properties PasswordLastSet, Enabled, "msDS-KeyVersionNumber", userAccountControl -ErrorAction Stop
    if (-not $krbtgt) {
        Write-Error "KRBTGT account not found on $targetServer."
        return
    }
} catch {
    Write-Error "Failed to retrieve KRBTGT account from $($targetServer): $($_.Exception.Message)"
    return
}

$lastSet = $krbtgt.PasswordLastSet
$currentKvno = $krbtgt."msDS-KeyVersionNumber"

Write-Host "[*] Current KRBTGT Password Last Set: $lastSet" -ForegroundColor Gray
Write-Host "[*] Current Key Version Number (kvno): $currentKvno" -ForegroundColor Gray

# 4. Enforce Cooldown Safety Check
if ($null -ne $lastSet) {
    $elapsedHours = (New-TimeSpan -Start $lastSet -End (Get-Date)).TotalHours
    if ($elapsedHours -lt $MinCooldownHours -and -not $Force) {
        $roundedHours = [math]::Round($elapsedHours, 1)
        Write-Warning "SAFETY INTERLOCK ENGAGED: The KRBTGT password was last set only $roundedHours hours ago."
        Write-Warning "Resetting KRBTGT again before the Kerberos ticket lifetime ($MinCooldownHours hours) has elapsed"
        Write-Warning "will purge the previous key from history and invalidate ALL active domain TGTs,"
        Write-Warning "causing enterprise-wide authentication failure for all users and services."
        Write-Warning "To override this interlock (e.g., during active incident containment), specify -Force."
        return
    }
}

# 5. Generate Cryptographically Secure 128-Character Password
$length = 128
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&amp;*()_+-=[]{}|;:,.&lt;&gt;?"
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$bytes = New-Object byte[] $length
$rng.GetBytes($bytes)

$securePassword = New-Object System.Security.SecureString
for ($i = 0; $i -lt $length; $i++) {
    $char = $chars[$bytes[$i] % $chars.Length]
    $securePassword.AppendChar($char)
}
$securePassword.MakeReadOnly()
$rng.Dispose()

# 6. Execute Password Reset via ShouldProcess
$confirmTarget = "KRBTGT account on $targetServer (Domain: $($domain.DNSRoot))"
if ($PSCmdlet.ShouldProcess($confirmTarget, "Reset KRBTGT account password and increment kvno")) {
    try {
        Set-ADAccountPassword -Identity $krbtgt -Server $targetServer -NewPassword $securePassword -Reset -ErrorAction Stop
        Write-Host "[+] KRBTGT password successfully reset on PDC Emulator ($targetServer)." -ForegroundColor Green

        # Re-query to verify kvno increment
        Start-Sleep -Seconds 2
        $updatedKrbtgt = Get-ADUser -Identity "krbtgt" -Server $targetServer -Properties PasswordLastSet, "msDS-KeyVersionNumber" -ErrorAction Stop
        Write-Host "[+] New Password Last Set: $($updatedKrbtgt.PasswordLastSet)" -ForegroundColor Green
        Write-Host "[+] New Key Version Number (kvno): $($updatedKrbtgt.'msDS-KeyVersionNumber')" -ForegroundColor Green

        # 7. Dispatch Active Directory Replication
        Write-Host "[*] Triggering Active Directory replication synchronization..." -ForegroundColor Cyan
        $repadmin = Get-Command -Name "repadmin.exe" -ErrorAction SilentlyContinue
        if ($repadmin) {
            &amp; repadmin.exe /syncall /AdeP | Out-Null
            Write-Host "[+] Active Directory replication triggered across all domain partitions." -ForegroundColor Green
        } else {
            try {
                Sync-ADObject -Identity $krbtgt.DistinguishedName -Server $targetServer -ErrorAction SilentlyContinue
                Write-Host "[+] Sync-ADObject invoked for KRBTGT account." -ForegroundColor Green
            } catch {
                Write-Warning "Could not trigger replication automatically. Ensure replication runs across all domain controllers."
            }
        }

        Write-Host ""
        Write-Host "=========================================================================" -ForegroundColor Yellow
        Write-Host "[IMPORTANT] Two-Step KRBTGT Password Rotation Protocol:" -ForegroundColor Yellow
        Write-Host " 1. This reset constitutes Step 1 of the rotation cycle." -ForegroundColor Yellow
        Write-Host " 2. Active Directory retains the previous key in history (index 1) so" -ForegroundColor Yellow
        Write-Host "    existing valid Kerberos tickets continue to function until expiration." -ForegroundColor Yellow
        Write-Host " 3. You MUST WAIT at least $MinCooldownHours to 24 hours for all active tickets" -ForegroundColor Yellow
        Write-Host "    to renew and for replication to converge across all domain controllers." -ForegroundColor Yellow
        Write-Host " 4. After the cooldown period, run this script again to perform Step 2," -ForegroundColor Yellow
        Write-Host "    which purges the pre-rotation key and completely invalidates any" -ForegroundColor Yellow
        Write-Host "    historical Golden, Diamond, or forged Kerberos tickets." -ForegroundColor Yellow
        Write-Host "=========================================================================" -ForegroundColor Yellow
    } catch {
        Write-Error "Failed to reset KRBTGT password: $($_.Exception.Message)"
    }
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-OPS-002] Enable and Configure the Active Directory Recycle Bin</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (Forest-wide configuration affecting all domains)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Forest Functional Level</xhtml:strong>: Windows Server 2008 R2 or higher</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/enable-recycle-bin.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Active Directory (AD) Recycle Bin is an essential disaster recovery, availability, and incident response capability. In modern enterprise environments, directory availability is directly tied to core organizational operations. Accidental administrative errors, script bugs, malicious insider sabotage, and destructive cyberattacks (such as ransomware operations deploying wipers like HermeticWiper or deleting Tier 0 infrastructure to inhibit incident response) pose critical risks to Active Directory object integrity.</xhtml:p>
        <xhtml:p>Enabling and properly configuring the Active Directory Recycle Bin provides vital security and operational defenses:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Center (GUI Configuration &amp; Recovery)</xhtml:h3>
        <xhtml:h4>1. Enabling the Recycle Bin (Forest Root Domain Controller)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller in the forest root domain with an account that is a member of the <xhtml:strong>Enterprise Admins</xhtml:strong> group.</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>In the left navigation pane, select the forest root domain node.</xhtml:li>
          <xhtml:li>In the right-hand <xhtml:strong>Tasks</xhtml:strong> pane, click <xhtml:strong>Enable Recycle Bin...</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the confirmation warning dialog informing that this action is irreversible, click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>A notification dialog will state that the feature will begin replicating across all Domain Controllers in the forest. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Refresh the Administrative Center interface; the "Enable Recycle Bin..." link will now be permanently grayed out.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Restoring Deleted Objects via ADAC</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>In the left navigation pane, expand the target domain node and click on the <xhtml:strong>Deleted Objects</xhtml:strong> container.</xhtml:li>
          <xhtml:li>Locate the deleted object(s) using the search bar or filter criteria.</xhtml:li>
          <xhtml:li>Right-click the object and select one of the following options:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Restore</xhtml:em>*: Restores the object directly to its original parent Organizational Unit.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Restore To...</xhtml:em>*: Allows specifying an alternative target Organizational Unit (required if the original parent OU was deleted or relocated).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Directory Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and activate the optional feature forest-wide, configure retention lifetimes, and verify container security.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-ADRecycleBin.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-ADRecycleBin.ps1">Download Script: Audit-ADRecycleBin.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-ADRecycleBin.ps1
# Description: Audits Active Directory Recycle Bin status, lifetime configurations, and container ACL permissions.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing Active Directory Recycle Bin Configuration ---" -ForegroundColor Cyan

$isVulnerable = $false

# 1. Verify Active Directory module availability
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Host "VULNERABLE: The ActiveDirectory PowerShell module is not available on this system." -ForegroundColor Red
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    return
}

Import-Module ActiveDirectory -ErrorAction SilentlyContinue

try {
    # 2. Check Forest and Forest Functional Level
    $forest = Get-ADForest -ErrorAction Stop
    $forestMode = $forest.ForestMode

    Write-Host "[*] Active Directory Forest: $($forest.Name)" -ForegroundColor Gray
    Write-Host "[*] Forest Functional Level: $($forestMode)" -ForegroundColor Gray

    $validModes = @("Windows2008R2Forest", "Windows2012Forest", "Windows2012R2Forest", "Windows2016Forest", "Windows2025Forest")
    if ($validModes -notcontains $forestMode) {
        Write-Host "VULNERABLE: Forest Functional Level '$($forestMode)' does not support Active Directory Recycle Bin (requires Windows Server 2008 R2 or higher)." -ForegroundColor Red
        $isVulnerable = $true
    }

    # 3. Check Optional Feature Enablement
    $recycleFeature = Get-ADOptionalFeature -Filter "Name -eq 'Recycle Bin Feature'" -Properties EnabledScopes -ErrorAction Stop
    $enabledScopes = $recycleFeature.EnabledScopes

    if ($enabledScopes -and ($enabledScopes -contains $forest.PartitionsContainer -or $enabledScopes.Count -gt 0)) {
        Write-Host "[+] Recycle Bin Feature is ENABLED forest-wide." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Active Directory Recycle Bin Feature is NOT enabled in forest '$($forest.Name)'." -ForegroundColor Red
        $isVulnerable = $true
    }

    # 4. Check Deleted Object Lifetime and Tombstone Lifetime
    $rootDse = Get-ADRootDSE -ErrorAction Stop
    $configNC = $rootDse.configurationNamingContext
    $dsPath = "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNC"

    $dsConfig = Get-ADObject -Identity $dsPath -Properties msDS-deletedObjectLifetime, tombstoneLifetime -ErrorAction Stop
    $dol = $dsConfig."msDS-deletedObjectLifetime"
    $tombstone = $dsConfig.tombstoneLifetime

    if ($null -eq $tombstone -or $tombstone -eq 0) {
        $effectiveTombstone = 60 # Legacy Windows 2000/2003 default
        Write-Host "[!] tombstoneLifetime attribute is not explicitly set (defaults to 60 days in legacy forests, or 180 days in modern forests)." -ForegroundColor Yellow
    } else {
        $effectiveTombstone = $tombstone
        Write-Host "[*] tombstoneLifetime: $($effectiveTombstone) days" -ForegroundColor Gray
    }

    if ($null -eq $dol) {
        Write-Host "[*] msDS-deletedObjectLifetime: (Not Set - defaults to tombstoneLifetime of $($effectiveTombstone) days)" -ForegroundColor Gray
    } else {
        Write-Host "[*] msDS-deletedObjectLifetime: $($dol) days" -ForegroundColor Gray
        if ($dol -lt 60) {
            Write-Host "VULNERABLE: msDS-deletedObjectLifetime is configured to less than 60 days ($($dol) days). Recovery window is excessively short." -ForegroundColor Red
            $isVulnerable = $true
        }
    }

    # 5. Audit Access Permissions on CN=Deleted Objects Container
    $domainDN = $rootDse.defaultNamingContext
    $deletedObjectsDN = "CN=Deleted Objects,$domainDN"

    Write-Host "[*] Auditing security permissions on: $($deletedObjectsDN)" -ForegroundColor Gray

    try {
        $deletedObjACL = Get-Acl -Path "AD:\$deletedObjectsDN" -ErrorAction Stop
        $suspiciousIdentities = @(
            "NT AUTHORITY\Authenticated Users",
            "Everyone",
            "BUILTIN\Users",
            "ANONYMOUS LOGON"
        )

        $flaggedAccess = $false
        foreach ($accessRule in $deletedObjACL.Access) {
            $identity = $accessRule.IdentityReference.Value
            foreach ($suspicious in $suspiciousIdentities) {
                if ($identity -like "*$suspicious*" -and $accessRule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow) {
                    Write-Host "VULNERABLE: Non-default permissive access granted to '$($identity)' on Deleted Objects container ($($accessRule.ActiveDirectoryRights))." -ForegroundColor Red
                    $flaggedAccess = $true
                    $isVulnerable = $true
                }
            }
        }

        if (-not $flaggedAccess) {
            Write-Host "[+] Permissions on Deleted Objects container are restricted to privileged administrators." -ForegroundColor Green
        }
    } catch {
        Write-Host "[*] Note: Unable to query Deleted Objects container ACL directly ($($_.Exception.Message))." -ForegroundColor Yellow
    }

} catch {
    Write-Host "VULNERABLE: Failed to complete Active Directory Recycle Bin audit. Error: $($_.Exception.Message)" -ForegroundColor Red
    $isVulnerable = $true
}

Write-Host "--------------------------------------------------------" -ForegroundColor Cyan
if ($isVulnerable) {
    Write-Host "Audit Result: VULNERABLE - Active Directory Recycle Bin configuration requires remediation." -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE - Active Directory Recycle Bin is enabled and correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Enable-ADRecycleBin.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enable-ADRecycleBin.ps1">Download Script: Enable-ADRecycleBin.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enable-ADRecycleBin.ps1
# Description: Validates forest prerequisites, enables Active Directory Recycle Bin forest-wide, and configures lifetimes.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Applying Hardening Requirement: Enable Active Directory Recycle Bin ---" -ForegroundColor Cyan

# 1. Verify Active Directory module
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    return
}

Import-Module ActiveDirectory -ErrorAction Stop

try {
    # 2. Forest and FFL Validation
    $forest = Get-ADForest -ErrorAction Stop
    $forestMode = $forest.ForestMode

    Write-Host "[*] Target Forest: $($forest.Name)" -ForegroundColor Gray
    Write-Host "[*] Current Forest Functional Level: $($forestMode)" -ForegroundColor Gray

    $validModes = @("Windows2008R2Forest", "Windows2012Forest", "Windows2012R2Forest", "Windows2016Forest", "Windows2025Forest")
    if ($validModes -notcontains $forestMode) {
        Write-Error "Cannot enable Recycle Bin. Forest functional level must be Windows Server 2008 R2 or higher (Current: $($forestMode)). Raise forest functional level first."
        return
    }

    # 3. Check and Enable Recycle Bin Feature
    $recycleBinFeature = Get-ADOptionalFeature -Filter "Name -eq 'Recycle Bin Feature'" -ErrorAction Stop
    $enabledScopes = $recycleBinFeature.EnabledScopes

    if (-not $enabledScopes -or $enabledScopes.Count -eq 0) {
        Write-Host "[+] Enabling Active Directory Recycle Bin optional feature in forest '$($forest.Name)'..." -ForegroundColor Yellow
        Enable-ADOptionalFeature -Identity $recycleBinFeature -Scope ForestOrConfigurationSet -Target $forest.Name -Confirm:$false -ErrorAction Stop
        Write-Host "[+] Active Directory Recycle Bin enabled successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] Active Directory Recycle Bin is already enabled in forest '$($forest.Name)'." -ForegroundColor Green
    }

    # 4. Configure / Verify msDS-deletedObjectLifetime
    $rootDse = Get-ADRootDSE -ErrorAction Stop
    $configNC = $rootDse.configurationNamingContext
    $dsPath = "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNC"

    $dsConfig = Get-ADObject -Identity $dsPath -Properties msDS-deletedObjectLifetime, tombstoneLifetime -ErrorAction Stop
    $tombstone = $dsConfig.tombstoneLifetime
    $currentDol = $dsConfig."msDS-deletedObjectLifetime"

    # Ensure tombstoneLifetime is at least 180 days
    if ($null -eq $tombstone -or $tombstone -lt 180) {
        Write-Host "[+] Setting tombstoneLifetime to 180 days on Directory Service configuration..." -ForegroundColor Yellow
        Set-ADObject -Identity $dsPath -Replace @{ tombstoneLifetime = 180 } -ErrorAction Stop
        Write-Host "[+] tombstoneLifetime updated to 180 days." -ForegroundColor Green
    } else {
        Write-Host "[+] tombstoneLifetime is currently configured to $($tombstone) days." -ForegroundColor Green
    }

    # Set explicit msDS-deletedObjectLifetime if missing or excessively low
    if ($null -eq $currentDol -or $currentDol -lt 180) {
        Write-Host "[+] Explicitly configuring msDS-deletedObjectLifetime to 180 days..." -ForegroundColor Yellow
        Set-ADObject -Identity $dsPath -Replace @{ "msDS-deletedObjectLifetime" = 180 } -ErrorAction Stop
        Write-Host "[+] msDS-deletedObjectLifetime configured to 180 days." -ForegroundColor Green
    } else {
        Write-Host "[+] msDS-deletedObjectLifetime is currently set to $($currentDol) days." -ForegroundColor Green
    }

    Write-Host "[+] Remediation completed successfully. Allow directory replication to synchronize across all Domain Controllers." -ForegroundColor Green

} catch {
    Write-Error "Failed to configure Active Directory Recycle Bin. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Operational Recovery Runbook (PowerShell)</xhtml:h3>
        <xhtml:p>Use these commands during incident response or accidental deletion triage to locate and restore deleted objects.</xhtml:p>
        <xhtml:h4>1. Discovering Deleted Objects</xhtml:h4>
        <xhtml:pre>
          <xhtml:code># List all deleted objects in the domain
Get-ADObject -SearchBase "CN=Deleted Objects,$((Get-ADRootDSE).defaultNamingContext)" -IncludeDeletedObjects -Filter 'isDeleted -eq $true' -Properties sAMAccountName, whenChanged, lastKnownParent, objectClass

# Find a deleted user by username
Get-ADObject -Filter "sAMAccountName -eq 'jsmith' -and isDeleted -eq $true" -IncludeDeletedObjects -Properties sAMAccountName, lastKnownParent

# Find all objects deleted within the last 24 hours
$cutoff = (Get-Date).AddDays(-1)
Get-ADObject -Filter "whenChanged -ge `$cutoff -and isDeleted -eq `$true" -IncludeDeletedObjects -Properties sAMAccountName, whenChanged, lastKnownParent</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Restoring a Single Deleted Object</xhtml:h4>
        <xhtml:pre>
          <xhtml:code># Restore a user object back to its original location (lastKnownParent)
Get-ADObject -Filter "sAMAccountName -eq 'jsmith' -and isDeleted -eq $true" -IncludeDeletedObjects | Restore-ADObject

# Restore an object to an alternative Organizational Unit
$targetOU = "OU=Quarantine,DC=corp,DC=domain,DC=com"
Get-ADObject -Filter "sAMAccountName -eq 'jsmith' -and isDeleted -eq $true" -IncludeDeletedObjects | Restore-ADObject -TargetPath $targetOU</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>3. Restoring Nested Organizational Units and Dependent Child Objects</xhtml:h4>
        <xhtml:p>When an Organizational Unit containing child objects (sub-OUs, users, groups, computers) is deleted, all objects move directly into <xhtml:code>CN=Deleted Objects</xhtml:code>. Because child objects reference their parent container, <xhtml:strong>the parent Organizational Unit must be restored first</xhtml:strong>, followed by subordinate child objects in hierarchical order:</xhtml:p>
        <xhtml:pre>
          <xhtml:code># Step 1: Restore the parent Organizational Unit first
Get-ADObject -Filter "objectClass -eq 'organizationalUnit' -and name -like 'Finance*' -and isDeleted -eq $true" -IncludeDeletedObjects | Restore-ADObject

# Step 2: Restore child objects (users, groups, computers) once parent OU exists
Get-ADObject -Filter "lastKnownParent -like '*Finance*' -and isDeleted -eq $true" -IncludeDeletedObjects | Restore-ADObject</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enable-ADRecycleBin.ps1
# Description: Validates forest prerequisites, enables Active Directory Recycle Bin forest-wide, and configures lifetimes.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Applying Hardening Requirement: Enable Active Directory Recycle Bin ---" -ForegroundColor Cyan

# 1. Verify Active Directory module
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    return
}

Import-Module ActiveDirectory -ErrorAction Stop

try {
    # 2. Forest and FFL Validation
    $forest = Get-ADForest -ErrorAction Stop
    $forestMode = $forest.ForestMode

    Write-Host "[*] Target Forest: $($forest.Name)" -ForegroundColor Gray
    Write-Host "[*] Current Forest Functional Level: $($forestMode)" -ForegroundColor Gray

    $validModes = @("Windows2008R2Forest", "Windows2012Forest", "Windows2012R2Forest", "Windows2016Forest", "Windows2025Forest")
    if ($validModes -notcontains $forestMode) {
        Write-Error "Cannot enable Recycle Bin. Forest functional level must be Windows Server 2008 R2 or higher (Current: $($forestMode)). Raise forest functional level first."
        return
    }

    # 3. Check and Enable Recycle Bin Feature
    $recycleBinFeature = Get-ADOptionalFeature -Filter "Name -eq 'Recycle Bin Feature'" -ErrorAction Stop
    $enabledScopes = $recycleBinFeature.EnabledScopes

    if (-not $enabledScopes -or $enabledScopes.Count -eq 0) {
        Write-Host "[+] Enabling Active Directory Recycle Bin optional feature in forest '$($forest.Name)'..." -ForegroundColor Yellow
        Enable-ADOptionalFeature -Identity $recycleBinFeature -Scope ForestOrConfigurationSet -Target $forest.Name -Confirm:$false -ErrorAction Stop
        Write-Host "[+] Active Directory Recycle Bin enabled successfully." -ForegroundColor Green
    } else {
        Write-Host "[+] Active Directory Recycle Bin is already enabled in forest '$($forest.Name)'." -ForegroundColor Green
    }

    # 4. Configure / Verify msDS-deletedObjectLifetime
    $rootDse = Get-ADRootDSE -ErrorAction Stop
    $configNC = $rootDse.configurationNamingContext
    $dsPath = "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$configNC"

    $dsConfig = Get-ADObject -Identity $dsPath -Properties msDS-deletedObjectLifetime, tombstoneLifetime -ErrorAction Stop
    $tombstone = $dsConfig.tombstoneLifetime
    $currentDol = $dsConfig."msDS-deletedObjectLifetime"

    # Ensure tombstoneLifetime is at least 180 days
    if ($null -eq $tombstone -or $tombstone -lt 180) {
        Write-Host "[+] Setting tombstoneLifetime to 180 days on Directory Service configuration..." -ForegroundColor Yellow
        Set-ADObject -Identity $dsPath -Replace @{ tombstoneLifetime = 180 } -ErrorAction Stop
        Write-Host "[+] tombstoneLifetime updated to 180 days." -ForegroundColor Green
    } else {
        Write-Host "[+] tombstoneLifetime is currently configured to $($tombstone) days." -ForegroundColor Green
    }

    # Set explicit msDS-deletedObjectLifetime if missing or excessively low
    if ($null -eq $currentDol -or $currentDol -lt 180) {
        Write-Host "[+] Explicitly configuring msDS-deletedObjectLifetime to 180 days..." -ForegroundColor Yellow
        Set-ADObject -Identity $dsPath -Replace @{ "msDS-deletedObjectLifetime" = 180 } -ErrorAction Stop
        Write-Host "[+] msDS-deletedObjectLifetime configured to 180 days." -ForegroundColor Green
    } else {
        Write-Host "[+] msDS-deletedObjectLifetime is currently set to $($currentDol) days." -ForegroundColor Green
    }

    Write-Host "[+] Remediation completed successfully. Allow directory replication to synchronize across all Domain Controllers." -ForegroundColor Green

} catch {
    Write-Error "Failed to configure Active Directory Recycle Bin. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-003" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-003] Establish and Maintain Group Policy ADMX Central Store</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers (SYSVOL Share)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/maintain-gpo-templates.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Group Policy Objects (GPOs) rely on XML-based Administrative Template files (<xhtml:code>.admx</xhtml:code>) and language-specific resource files (<xhtml:code>.adml</xhtml:code>) to display registry-based policy settings within administrative tools.</xhtml:p>
        <xhtml:p>By default, the Group Policy Management Editor loads templates from the local computer's <xhtml:code>%SystemRoot%\PolicyDefinitions</xhtml:code> folder. In an enterprise AD environment, this behavior introduces several security and operational risks: 1. <xhtml:strong>Configuration Drift</xhtml:strong>: If different Domain Controllers or management workstations have different template versions installed, editing GPOs can result in missing configurations, corrupted settings, or inadvertent reversion of newer security settings. 2. <xhtml:strong>Missing Security Controls</xhtml:strong>: As operating systems evolve, new security controls (such as disabling legacy name resolution or enforcing LSA protection) are introduced in newer templates. Without updated templates, administrators cannot manage these settings via the GPMC GUI.</xhtml:p>
        <xhtml:p>Establishing the <xhtml:strong>Central Store</xhtml:strong> in the SYSVOL share ensures that all administrators edit GPOs using a single, authoritative set of administrative templates.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Central Store Establishment (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a Domain Controller with <xhtml:strong>Schema Admins</xhtml:strong> or <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Open File Explorer and navigate to the local SYSVOL Policies folder:</xhtml:li>
          <xhtml:li>
            <xhtml:code>C:\Windows\SYSVOL\sysvol\&lt;Domain_FQDN&gt;\Policies</xhtml:code> (or use the UNC path: <xhtml:code>\\localhost\SYSVOL\&lt;Domain_FQDN&gt;\Policies</xhtml:code>).</xhtml:li>
          <xhtml:li>Create a new folder named <xhtml:code>PolicyDefinitions</xhtml:code>.</xhtml:li>
          <xhtml:li>Create language-specific subdirectories inside it based on your environment (e.g. <xhtml:code>en-US</xhtml:code>).</xhtml:li>
          <xhtml:li>Copy the contents of the local administrative template directory <xhtml:code>C:\Windows\PolicyDefinitions</xhtml:code> (all <xhtml:code>.admx</xhtml:code> files) into the newly created <xhtml:code>PolicyDefinitions</xhtml:code> folder in SYSVOL.</xhtml:li>
          <xhtml:li>Copy the local <xhtml:code>.adml</xhtml:code> files from <xhtml:code>C:\Windows\PolicyDefinitions\en-US</xhtml:code> into the <xhtml:code>en-US</xhtml:code> subfolder in SYSVOL.</xhtml:li>
          <xhtml:li>To update templates in an offline, air-gapped environment, manually transfer the latest Administrative Templates (downloaded as <xhtml:code>.msi</xhtml:code> packages from Microsoft) to the domain controller, extract them, and copy the new <xhtml:code>.admx</xhtml:code> and <xhtml:code>.adml</xhtml:code> files into the SYSVOL Central Store, replacing older versions.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and initialize the Central Store folder structure.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-GPOCentralStore.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-GPOCentralStore.ps1">Download Script: Audit-GPOCentralStore.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-GPOCentralStore.ps1
# Description: Audits the existence of the GPO Central Store in SYSVOL.

Import-Module ActiveDirectory

Write-Host "--- Auditing Group Policy Central Store ---" -ForegroundColor Cyan

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (Test-Path -Path $CentralStorePath) {
        Write-Host "`nStatus: Compliant. Group Policy Central Store is established at:" -ForegroundColor Green
        Write-Host "    $CentralStorePath" -ForegroundColor White
        
        $AdmxFiles = Get-ChildItem -Path $CentralStorePath -Filter *.admx
        Write-Host "    Found $($AdmxFiles.Count) ADMX templates in the store." -ForegroundColor Green
    } else {
        Write-Host "`nVULNERABLE: Group Policy Central Store does NOT exist. Expected location:" -ForegroundColor Red
        Write-Host "    $CentralStorePath" -ForegroundColor Red
    }
} catch {
    Write-Host "VULNERABLE: Could not query Active Directory for SYSVOL path. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Create-GPOCentralStore.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Create-GPOCentralStore.ps1">Download Script: Create-GPOCentralStore.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Create-GPOCentralStore.ps1
# Description: Initializes the Central Store directory structure in SYSVOL.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Initialize GPO Central Store..." -ForegroundColor Cyan

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (-not (Test-Path -Path $CentralStorePath)) {
        New-Item -ItemType Directory -Path $CentralStorePath -Force -ErrorAction Stop | Out-Null
        # Create standard language folder
        New-Item -ItemType Directory -Path (Join-Path $CentralStorePath "en-US") -Force -ErrorAction Stop | Out-Null
        
        Write-Host "[+] Group Policy Central Store initialized successfully." -ForegroundColor Green
        Write-Host "    Path: $CentralStorePath" -ForegroundColor White
        Write-Host "    Please copy the latest .admx and .adml files to this directory." -ForegroundColor Yellow
    } else {
        Write-Host "[+] Central Store is already initialized at: $CentralStorePath" -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to initialize GPO Central Store. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Create-GPOCentralStore.ps1
# Description: Initializes the Central Store directory structure in SYSVOL.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Initialize GPO Central Store..." -ForegroundColor Cyan

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (-not (Test-Path -Path $CentralStorePath)) {
        New-Item -ItemType Directory -Path $CentralStorePath -Force -ErrorAction Stop | Out-Null
        # Create standard language folder
        New-Item -ItemType Directory -Path (Join-Path $CentralStorePath "en-US") -Force -ErrorAction Stop | Out-Null
        
        Write-Host "[+] Group Policy Central Store initialized successfully." -ForegroundColor Green
        Write-Host "    Path: $CentralStorePath" -ForegroundColor White
        Write-Host "    Please copy the latest .admx and .adml files to this directory." -ForegroundColor Yellow
    } else {
        Write-Host "[+] Central Store is already initialized at: $CentralStorePath" -ForegroundColor Green
    }
} catch {
    Write-Error "Failed to initialize GPO Central Store. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-004" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-004] Implement Third-Party and Custom GPO Templates for COTS Hardening</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Members (Clients and Servers)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11, Windows Server 2016 and above</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/use-third-party-templates.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Group Policy Objects (GPOs) natively manage core Windows operating system components but lack administrative control definitions for third-party Commercial Off-The-Shelf (COTS) software (such as Google Chrome, Microsoft Edge, Adobe Acrobat Reader) and advanced security guide extensions.</xhtml:p>
        <xhtml:p>Implementing third-party and custom GPO templates provides the following benefits: 1. <xhtml:strong>Centralized Configuration</xhtml:strong>: Administrators can enforce security configurations across all enterprise workstations and member servers (e.g. disabling insecure browser protocols, locking PDF execution properties) directly from the Group Policy Management Console. 2. <xhtml:strong>Reduced Attack Surface</xhtml:strong>: Custom templates (such as <xhtml:a href="https://github.com/Harvester57/Security-ADMX">Security-ADMX GitHub Repository</xhtml:a> or the Microsoft Security Guide template) expose hidden or advanced registry configurations, allowing administrators to restrict features like WDigest authentication or LSA credential caching that are not exposed in standard out-of-the-box Windows templates. 3. <xhtml:strong>Consistency</xhtml:strong>: Linking COTS hardening GPOs ensures that third-party applications remain compliant with corporate security baselines, preventing local user overrides.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Central Store Importing (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log on to a management workstation or Domain Controller with <xhtml:strong>Domain Admins</xhtml:strong> credentials.</xhtml:li>
          <xhtml:li>Download the official Administrative Templates from the software manufacturer's website (e.g. Microsoft Edge Enterprise templates, Google Chrome templates).</xhtml:li>
          <xhtml:li>Extract the downloaded files to locate the <xhtml:code>.admx</xhtml:code> files and matching <xhtml:code>.adml</xhtml:code> language-specific resource files (typically in <xhtml:code>en-US</xhtml:code> subfolders).</xhtml:li>
          <xhtml:li>Navigate to the Central Store on a Domain Controller:</xhtml:li>
          <xhtml:li>
            <xhtml:code>\\&lt;Domain_FQDN&gt;\SYSVOL\&lt;Domain_FQDN&gt;\Policies\PolicyDefinitions</xhtml:code>
          </xhtml:li>
          <xhtml:li>Copy the <xhtml:code>.admx</xhtml:code> files into the root of the <xhtml:code>PolicyDefinitions</xhtml:code> directory.</xhtml:li>
          <xhtml:li>Copy the <xhtml:code>.adml</xhtml:code> files into the language subfolder matching the language (e.g. <xhtml:code>PolicyDefinitions\en-US</xhtml:code>).</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) and edit a target hardening GPO. The new settings will appear under <xhtml:strong>Computer Configuration &gt; Policies &gt; Administrative Templates &gt; [Software Name]</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts to audit and import custom templates.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-ThirdPartyTemplates.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-ThirdPartyTemplates.ps1">Download Script: Audit-ThirdPartyTemplates.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-ThirdPartyTemplates.ps1
# Description: Checks the GPO Central Store for common third-party templates.

Import-Module ActiveDirectory

Write-Host "--- Auditing Third-Party GPO Templates ---" -ForegroundColor Cyan

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (Test-Path -Path $CentralStorePath) {
        $Templates = @{
            "Microsoft Edge" = "msedge.admx"
            "Google Chrome" = "chrome.admx"
            "Adobe Acrobat" = "Acrobat.admx"
            "MS Security Guide" = "SecGuide.admx"
        }
        
        Write-Host "`nChecking for common templates in Central Store:" -ForegroundColor Yellow
        foreach ($key in $Templates.Keys) {
            $file = $Templates[$key]
            $fullPath = Join-Path $CentralStorePath $file
            
            if (Test-Path -Path $fullPath) {
                Write-Host "    - [FOUND] $key ($file)" -ForegroundColor Green
            } else {
                Write-Host "    - [MISSING] $key ($file)" -ForegroundColor Yellow
            }
        }
    } else {
        Write-Host "VULNERABLE: Group Policy Central Store does not exist. Cannot audit templates." -ForegroundColor Red
    }
} catch {
    Write-Host "VULNERABLE: Could not query Active Directory. Error: $($_.Exception.Message)" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Import-ThirdPartyTemplate.ps1)</xhtml:h4>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Import-ThirdPartyTemplate.ps1">Download Script: Import-ThirdPartyTemplate.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Import-ThirdPartyTemplate.ps1
# Description: Copies a specified ADMX and ADML template to the Central Store.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Copy GPO Templates to Central Store..." -ForegroundColor Cyan

# Define local source paths for templates (to be populated by administrator)
$SourceAdmx = "C:\SourceTemplates\msedge.admx"
$SourceAdml = "C:\SourceTemplates\en-US\msedge.adml"

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (-not (Test-Path -Path $CentralStorePath)) {
        Write-Error "GPO Central Store is not initialized. Please establish the Central Store first."
        exit 1
    }
    
    if ((Test-Path -Path $SourceAdmx) -and (Test-Path -Path $SourceAdml)) {
        # Copy ADMX file
        Copy-Item -Path $SourceAdmx -Destination $CentralStorePath -Force -ErrorAction Stop
        Write-Host "[+] Copied ADMX: $(Split-Path $SourceAdmx -Leaf) to Central Store." -ForegroundColor Green
        
        # Copy ADML file to matching subfolder
        $LangDir = Join-Path $CentralStorePath "en-US"
        if (-not (Test-Path -Path $LangDir)) {
            New-Item -ItemType Directory -Path $LangDir -Force -ErrorAction Stop | Out-Null
        }
        Copy-Item -Path $SourceAdml -Destination $LangDir -Force -ErrorAction Stop
        Write-Host "[+] Copied ADML: $(Split-Path $SourceAdml -Leaf) to Central Store en-US subfolder." -ForegroundColor Green
    } else {
        Write-Warning "Source template files not found at specified paths. Please ensure templates are downloaded locally."
    }
} catch {
    Write-Error "Failed to copy template files. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Import-ThirdPartyTemplate.ps1
# Description: Copies a specified ADMX and ADML template to the Central Store.

Import-Module ActiveDirectory

Write-Host "Applying hardening requirement: Copy GPO Templates to Central Store..." -ForegroundColor Cyan

# Define local source paths for templates (to be populated by administrator)
$SourceAdmx = "C:\SourceTemplates\msedge.admx"
$SourceAdml = "C:\SourceTemplates\en-US\msedge.adml"

try {
    $Domain = Get-ADDomain -ErrorAction Stop
    $CentralStorePath = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies\PolicyDefinitions"
    
    if (-not (Test-Path -Path $CentralStorePath)) {
        Write-Error "GPO Central Store is not initialized. Please establish the Central Store first."
        exit 1
    }
    
    if ((Test-Path -Path $SourceAdmx) -and (Test-Path -Path $SourceAdml)) {
        # Copy ADMX file
        Copy-Item -Path $SourceAdmx -Destination $CentralStorePath -Force -ErrorAction Stop
        Write-Host "[+] Copied ADMX: $(Split-Path $SourceAdmx -Leaf) to Central Store." -ForegroundColor Green
        
        # Copy ADML file to matching subfolder
        $LangDir = Join-Path $CentralStorePath "en-US"
        if (-not (Test-Path -Path $LangDir)) {
            New-Item -ItemType Directory -Path $LangDir -Force -ErrorAction Stop | Out-Null
        }
        Copy-Item -Path $SourceAdml -Destination $LangDir -Force -ErrorAction Stop
        Write-Host "[+] Copied ADML: $(Split-Path $SourceAdml -Leaf) to Central Store en-US subfolder." -ForegroundColor Green
    } else {
        Write-Warning "Source template files not found at specified paths. Please ensure templates are downloaded locally."
    }
} catch {
    Write-Error "Failed to copy template files. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-005" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-005] Configure Dedicated WSUS for Tier 0</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Tier 0 Administration Workstations (PAWs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/configure-dedicated-tier0-wsus.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Server Update Services (WSUS) role allows administrators to centralize the approval and distribution of security updates and patches. However, update services execute code with system privileges.</xhtml:p>
        <xhtml:p>If a shared, mutualized WSUS server (managed by Tier 1 or Tier 2 administrators) is used to patch Tier 0 Domain Controllers: 1. <xhtml:strong>Lateral Movement Target</xhtml:strong>: A compromise of the shared WSUS server or its database allows an attacker to inject malicious metadata, forcing Domain Controllers to execute arbitrary code or load compromised updates. 2. <xhtml:strong>Bypasses Administration Isolation</xhtml:strong>: Standard network administrators could inadvertently or maliciously deploy payloads to Tier 0 servers. 3. <xhtml:strong>HTTP Traffic Manipulation</xhtml:strong>: If WSUS communication is configured over cleartext HTTP (the default port 8530), attackers inside the network can perform man-in-the-middle attacks to inject custom update packages.</xhtml:p>
        <xhtml:p>To mitigate these threats, Tier 0 Domain Controllers and PAWs must pull updates from a dedicated WSUS server located inside the Tier 0 security boundary, configured exclusively with SSL/TLS encryption.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration</xhtml:h3>
        <xhtml:h4>1. Enforce HTTPS for WSUS in GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Group Policy Management</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting Tier 0 systems (e.g., <xhtml:code>GPO_Hardening_DomainControllers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click the <xhtml:strong>Specify intranet Microsoft update service location</xhtml:strong> policy.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set the intranet update service and status server properties to point to the dedicated, secure Tier 0 WSUS server:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet update service for detecting updates</xhtml:em>*: <xhtml:code>https://wsust0.corp.local:8531</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet statistics server</xhtml:em>*: <xhtml:code>https://wsust0.corp.local:8531</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the alternate download server</xhtml:em>*: <xhtml:code>https://wsust0.corp.local:8531</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> and link the GPO to the Domain Controllers and PAW OUs.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure SSL on the WSUS Server</xhtml:h4>
        <xhtml:p>On the dedicated Tier 0 WSUS server: 1. Open <xhtml:strong>IIS Manager</xhtml:strong> (<xhtml:code>inetmgr.exe</xhtml:code>). 2. Bind an SSL certificate (issued by a trusted PKI) to port 8531 on the WSUS Administration Web Site. 3. In the middle pane, double-click <xhtml:strong>SSL Settings</xhtml:strong> on the virtual directories (<xhtml:code>SimpleAuthWebService</xhtml:code>, <xhtml:code>DSSAuthWebService</xhtml:code>, <xhtml:code>ClientWebService</xhtml:code>, <xhtml:code>APIRemoting30</xhtml:code>). 4. Check <xhtml:strong>Require SSL</xhtml:strong> and click <xhtml:strong>Apply</xhtml:strong>. 5. Execute the WSUS configuration command to activate SSL bindings: <xhtml:code>C:\Program Files\Update Services\Tools\wsusutil.exe configuressl wsust0.corp.local</xhtml:code>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to apply the dedicated WSUS target server configuration locally via registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-LocalWsusServer.ps1">Download Script: Set-LocalWsusServer.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-LocalWsusServer.ps1
# Description: Configures the local client registry to utilize the dedicated Tier 0 WSUS over HTTPS.

Write-Host "Applying hardening requirement: Configure Dedicated WSUS for Tier 0..." -ForegroundColor Cyan

$WsusRegPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"
$WsusServerUrl = "https://wsust0.corp.local:8531"

if (-not (Test-Path $WsusRegPath)) {
    New-Item -Path $WsusRegPath -Force | Out-Null
}

# 1. Configure target WSUS server values
Set-ItemProperty -Path $WsusRegPath -Name "WUServer" -Value $WsusServerUrl -Type String -ErrorAction Stop
Set-ItemProperty -Path $WsusRegPath -Name "WUStatusServer" -Value $WsusServerUrl -Type String -ErrorAction Stop

# 2. Force Windows Update configuration to use local settings
$UpdateAuPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU"
if (-not (Test-Path $UpdateAuPath)) {
    New-Item -Path $UpdateAuPath -Force | Out-Null
}
Set-ItemProperty -Path $UpdateAuPath -Name "UseWUServer" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "[+] Local system configured to use secure WSUS server: $WsusServerUrl" -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify active WSUS configurations:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-WsusConfigStatus.ps1">Download Script: Get-WsusConfigStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WsusConfigStatus.ps1
# Description: Audits local WSUS configuration settings.

$WsusRegPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"

Write-Host "Checking Windows Update registry parameters..." -ForegroundColor Cyan

if (Test-Path $WsusRegPath) {
    $WusVal = Get-ItemProperty -Path $WsusRegPath -Name "WUServer" -ErrorAction SilentlyContinue
    if ($null -ne $WusVal) {
        $WusServer = $WusVal.WUServer
        
        # Check if using HTTPS
        if ($WusServer -like "https://*") {
            Write-Host "[+] WUServer: $WusServer (Secure HTTPS Connection)." -ForegroundColor Green
        } else {
            Write-Host "[-] WUServer: $WusServer (Insecure HTTP Connection - Action Required)." -ForegroundColor Red
        }
    } else {
        Write-Host "[-] WUServer is not configured." -ForegroundColor Yellow
    }
} else {
    Write-Host "[-] Windows Update policies are not defined." -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-LocalWsusServer.ps1
# Description: Configures the local client registry to utilize the dedicated Tier 0 WSUS over HTTPS.

Write-Host "Applying hardening requirement: Configure Dedicated WSUS for Tier 0..." -ForegroundColor Cyan

$WsusRegPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"
$WsusServerUrl = "https://wsust0.corp.local:8531"

if (-not (Test-Path $WsusRegPath)) {
    New-Item -Path $WsusRegPath -Force | Out-Null
}

# 1. Configure target WSUS server values
Set-ItemProperty -Path $WsusRegPath -Name "WUServer" -Value $WsusServerUrl -Type String -ErrorAction Stop
Set-ItemProperty -Path $WsusRegPath -Name "WUStatusServer" -Value $WsusServerUrl -Type String -ErrorAction Stop

# 2. Force Windows Update configuration to use local settings
$UpdateAuPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU"
if (-not (Test-Path $UpdateAuPath)) {
    New-Item -Path $UpdateAuPath -Force | Out-Null
}
Set-ItemProperty -Path $UpdateAuPath -Name "UseWUServer" -Value 1 -Type DWord -ErrorAction Stop

Write-Host "[+] Local system configured to use secure WSUS server: $WsusServerUrl" -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-OPS-006] Redirect Default Users and Computers Containers</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Controllers (Domain-wide structural policy)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows Server 2025</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Domain Functional Level</xhtml:strong>: Windows Server 2003 or higher</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/redirect-default-containers.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In default Active Directory deployments, newly provisioned user and computer accounts are automatically instantiated within two legacy default containers located at the root of the domain: <xhtml:em> </xhtml:em>
          <xhtml:em>Default Users Container</xhtml:em>
          <xhtml:em>: `CN=Users,DC=domain,DC=com` </xhtml:em>
          <xhtml:strong>Default Computers Container</xhtml:strong>: <xhtml:code>CN=Computers,DC=domain,DC=com</xhtml:code>
        </xhtml:p>
        <xhtml:p>From an enterprise security and systems architecture perspective, placing active operational assets in these default locations creates severe defensive gaps, policy blind spots, and lateral movement vulnerabilities.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Active Directory Administrative Center &amp; Native CLI Tools (Preferred)</xhtml:h3>
        <xhtml:p>Execute the following procedure on a Domain Controller using an account with <xhtml:strong>Domain Admins</xhtml:strong> or <xhtml:strong>Enterprise Admins</xhtml:strong> privileges.</xhtml:p>
        <xhtml:h4>1. Create and Protect Staging Organizational Units</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open <xhtml:strong>Active Directory Administrative Center</xhtml:strong> (<xhtml:code>dsac.exe</xhtml:code>) or <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Ensure <xhtml:strong>View -&gt; Advanced Features</xhtml:strong> is enabled in <xhtml:code>dsa.msc</xhtml:code>.</xhtml:li>
          <xhtml:li>Create two dedicated staging Organizational Units at the appropriate administrative level (e.g., at the domain root or under a dedicated <xhtml:code>Staging</xhtml:code> hierarchy):</xhtml:li>
          <xhtml:li>* <xhtml:code>OU=Staging-Computers,DC=domain,DC=com</xhtml:code>
          </xhtml:li>
          <xhtml:li>* <xhtml:code>OU=Staging-Users,DC=domain,DC=com</xhtml:code>
          </xhtml:li>
          <xhtml:li>For both OUs, verify that accidental deletion protection is active:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click the OU, select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>
            <xhtml:em>, navigate to the </xhtml:em>
            <xhtml:em>Object</xhtml:em>* tab.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Verify that </xhtml:em>
            <xhtml:em>Protect object from accidental deletion</xhtml:em>
            <xhtml:em> is checked. Click </xhtml:em>
            <xhtml:em>OK</xhtml:em>*.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Link Baseline Quarantine Group Policy Objects</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create and link a dedicated quarantine baseline GPO to <xhtml:code>OU=Staging-Computers</xhtml:code>:</xhtml:li>
          <xhtml:li>* Enforce Windows LAPS with randomized high-entropy passwords.</xhtml:li>
          <xhtml:li>* Enable Windows Firewall for all profiles with default inbound block rules, permitting only essential management traffic from authorized deployment servers and DCs.</xhtml:li>
          <xhtml:li>* Enable Windows Defender Antivirus real-time protection and Credential Guard.</xhtml:li>
          <xhtml:li>Link appropriate baseline policies to <xhtml:code>OU=Staging-Users</xhtml:code> (e.g., enforce Kerberos pre-authentication, smart card enforcement, or account disablement pending onboarding validation).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Execute Container Redirection</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open an elevated Command Prompt (<xhtml:code>cmd.exe</xhtml:code>) on a Domain Controller.</xhtml:li>
          <xhtml:li>Redirect the default computer container to the new staging OU:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>redircmp.exe "OU=Staging-Computers,DC=domain,DC=com"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>(Replace `DC=domain,DC=com` with the actual Distinguished Name of the domain).</xhtml:em>
          </xhtml:li>
          <xhtml:li>Verify command output:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Redirection was successful.</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Redirect the default user container to the new staging OU:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>redirusr.exe "OU=Staging-Users,DC=domain,DC=com"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em>(Replace `DC=domain,DC=com` with the actual Distinguished Name of the domain).</xhtml:em>
          </xhtml:li>
          <xhtml:li>Verify command output:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Redirection was successful.</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Delegate Computer Joining Permissions on Staging-Computers OU</xhtml:h4>
        <xhtml:p>If authorized provisioning accounts or automated imaging systems (SCCM/MECM, MDT, WDS) need to join computers: 1. In <xhtml:code>dsa.msc</xhtml:code>, right-click <xhtml:code>OU=Staging-Computers</xhtml:code> and select <xhtml:strong>Delegate Control...</xhtml:strong>. 2. Add the designated provisioning service account or security group (e.g., <xhtml:code>SVC_ComputerJoiner_gMSA</xhtml:code> or <xhtml:code>GG_Workstation_Provisioning</xhtml:code>). 3. Select <xhtml:strong>Create a custom task to delegate</xhtml:strong> -&gt; <xhtml:strong>Next</xhtml:strong>. 4. Select <xhtml:strong>Only the following objects in the folder</xhtml:strong> -&gt; check <xhtml:strong>Computer objects</xhtml:strong> -&gt; check <xhtml:strong>Create selected objects in this folder</xhtml:strong>. 5. Click <xhtml:strong>Next</xhtml:strong>, grant <xhtml:code>Read</xhtml:code> and <xhtml:code>Write</xhtml:code> permissions for computer properties, and finish the wizard.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Automated Administration (Audit &amp; Remediation)</xhtml:h3>
        <xhtml:p>The following PowerShell scripts run natively on <xhtml:strong>Windows PowerShell 5.1</xhtml:strong> on Domain Controllers with the Active Directory RSAT module installed.</xhtml:p>
        <xhtml:h4>1. Local Audit (Audit-DefaultContainers.ps1)</xhtml:h4>
        <xhtml:p>This script audits the redirection state of both user and computer containers, validates accidental deletion protection, verifies GPO linkages, and flags any unmanaged residual accounts remaining in legacy containers.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-DefaultContainers.ps1">Download Script: Audit-DefaultContainers.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-DefaultContainers.ps1
# Description: Audits Active Directory default user and computer container redirection,
#              verifies accidental deletion protection, checks GPO linkage, and inventories residual accounts.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing Active Directory Default Containers Redirection ---" -ForegroundColor Cyan

# 1. Verify Active Directory module availability
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Host "VULNERABLE: The ActiveDirectory PowerShell module is not installed or available on this system." -ForegroundColor Red
    exit 1
}

Import-Module ActiveDirectory

$isVulnerable = $false

try {
    $domain = Get-ADDomain -ErrorAction Stop
    $domainDN = $domain.DistinguishedName
    $defaultComputersDN = "CN=Computers,$($domainDN)"
    $defaultUsersDN = "CN=Users,$($domainDN)"

    Write-Host "[i] Domain Distinguished Name: $($domainDN)" -ForegroundColor Gray
    Write-Host "[i] Domain Functional Level : $($domain.DomainMode)" -ForegroundColor Gray
    Write-Host ""

    # -------------------------------------------------------------
    # 2. Check Computers Container Redirection
    # -------------------------------------------------------------
    Write-Host "Checking Computers Container Configuration..." -ForegroundColor Yellow
    $currentCompContainer = $domain.ComputersContainer
    Write-Host "[i] Current Computers Container: $($currentCompContainer)" -ForegroundColor Gray

    if ($currentCompContainer -eq $defaultComputersDN) {
        Write-Host "VULNERABLE: Default Computers container is NOT redirected. Newly joined computers land in unmanaged 'CN=Computers'." -ForegroundColor Red
        $isVulnerable = $true
    } else {
        # Verify the redirected container is an OU
        $compTarget = Get-ADObject -Identity $currentCompContainer -Properties ProtectedFromAccidentalDeletion, gPLink -ErrorAction SilentlyContinue
        if ($null -eq $compTarget) {
            Write-Host "VULNERABLE: The redirected Computers target container does not exist: $($currentCompContainer)" -ForegroundColor Red
            $isVulnerable = $true
        } elseif ($compTarget.ObjectClass -ne "organizationalUnit") {
            Write-Host "VULNERABLE: Computers container is redirected to object class '$($compTarget.ObjectClass)', NOT an Organizational Unit. GPOs cannot be linked directly." -ForegroundColor Red
            $isVulnerable = $true
        } else {
            Write-Host "[+] Computers container is redirected to an Organizational Unit." -ForegroundColor Green

            # Check accidental deletion protection
            if ($compTarget.ProtectedFromAccidentalDeletion) {
                Write-Host "[+] Computers OU has Accidental Deletion Protection ENABLED." -ForegroundColor Green
            } else {
                Write-Host "VULNERABLE: Computers OU '$($compTarget.Name)' has Accidental Deletion Protection DISABLED." -ForegroundColor Red
                $isVulnerable = $true
            }

            # Check GPO linkage
            if ([string]::IsNullOrEmpty($compTarget.gPLink)) {
                Write-Host "WARNING: Computers target OU has NO Group Policy Objects linked. Newly joined machines will not receive hardening baselines." -ForegroundColor Yellow
            } else {
                Write-Host "[+] Computers target OU has active Group Policy Object(s) linked." -ForegroundColor Green
            }
        }
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 3. Check Users Container Redirection
    # -------------------------------------------------------------
    Write-Host "Checking Users Container Configuration..." -ForegroundColor Yellow
    $currentUserContainer = $domain.UsersContainer
    Write-Host "[i] Current Users Container: $($currentUserContainer)" -ForegroundColor Gray

    if ($currentUserContainer -eq $defaultUsersDN) {
        Write-Host "VULNERABLE: Default Users container is NOT redirected. Newly created users land in unmanaged 'CN=Users'." -ForegroundColor Red
        $isVulnerable = $true
    } else {
        # Verify the redirected container is an OU
        $userTarget = Get-ADObject -Identity $currentUserContainer -Properties ProtectedFromAccidentalDeletion, gPLink -ErrorAction SilentlyContinue
        if ($null -eq $userTarget) {
            Write-Host "VULNERABLE: The redirected Users target container does not exist: $($currentUserContainer)" -ForegroundColor Red
            $isVulnerable = $true
        } elseif ($userTarget.ObjectClass -ne "organizationalUnit") {
            Write-Host "VULNERABLE: Users container is redirected to object class '$($userTarget.ObjectClass)', NOT an Organizational Unit. GPOs cannot be linked directly." -ForegroundColor Red
            $isVulnerable = $true
        } else {
            Write-Host "[+] Users container is redirected to an Organizational Unit." -ForegroundColor Green

            # Check accidental deletion protection
            if ($userTarget.ProtectedFromAccidentalDeletion) {
                Write-Host "[+] Users OU has Accidental Deletion Protection ENABLED." -ForegroundColor Green
            } else {
                Write-Host "VULNERABLE: Users OU '$($userTarget.Name)' has Accidental Deletion Protection DISABLED." -ForegroundColor Red
                $isVulnerable = $true
            }

            # Check GPO linkage
            if ([string]::IsNullOrEmpty($userTarget.gPLink)) {
                Write-Host "WARNING: Users target OU has NO Group Policy Objects linked. Newly provisioned users will not receive hardening baselines." -ForegroundColor Yellow
            } else {
                Write-Host "[+] Users target OU has active Group Policy Object(s) linked." -ForegroundColor Green
            }
        }
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 4. Inventory Residual Accounts in Legacy Containers
    # -------------------------------------------------------------
    Write-Host "Inventorying Residual Non-Built-in Objects in Default Containers..." -ForegroundColor Yellow

    # Residual computers in CN=Computers
    $strayComputers = Get-ADComputer -SearchBase $defaultComputersDN -SearchScope OneLevel -Filter * -ErrorAction SilentlyContinue
    if ($strayComputers) {
        $count = ($strayComputers | Measure-Object).Count
        Write-Host "WARNING: Found $($count) computer object(s) remaining in legacy default 'CN=Computers'. These should be migrated to appropriate tier OUs." -ForegroundColor Yellow
        foreach ($comp in $strayComputers | Select-Object -First 5) {
            Write-Host "  - $($comp.Name) (Enabled: $($comp.Enabled))" -ForegroundColor Gray
        }
        if ($count -gt 5) {
            Write-Host "  - ... and $($count - 5) more computer(s)." -ForegroundColor Gray
        }
    } else {
        Write-Host "[+] Legacy default 'CN=Computers' container has no residual computer objects." -ForegroundColor Green
    }

    # Residual non-system users in CN=Users
    $builtinSids = @(
        "$($domain.DomainSID)-500", # Administrator
        "$($domain.DomainSID)-501", # Guest
        "$($domain.DomainSID)-502"  # krbtgt
    )
    $strayUsers = Get-ADUser -SearchBase $defaultUsersDN -SearchScope OneLevel -Filter * -ErrorAction SilentlyContinue | Where-Object {
        $builtinSids -notcontains $_.SID.Value -and $_.SamAccountName -ne "SUPPORT_388945a0"
    }
    if ($strayUsers) {
        $userCount = ($strayUsers | Measure-Object).Count
        Write-Host "WARNING: Found $($userCount) non-built-in user account(s) remaining in legacy default 'CN=Users'. These should be evaluated and migrated to tier OUs." -ForegroundColor Yellow
        foreach ($usr in $strayUsers | Select-Object -First 5) {
            Write-Host "  - $($usr.SamAccountName) (Enabled: $($usr.Enabled))" -ForegroundColor Gray
        }
        if ($userCount -gt 5) {
            Write-Host "  - ... and $($userCount - 5) more user(s)." -ForegroundColor Gray
        }
    } else {
        Write-Host "[+] Legacy default 'CN=Users' container contains only default built-in security principals." -ForegroundColor Green
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 5. Final Compliance Assessment
    # -------------------------------------------------------------
    if ($isVulnerable) {
        Write-Host "STATUS: NON-COMPLIANT - Default container redirection is not fully configured or protected." -ForegroundColor Red
        exit 1
    } else {
        Write-Host "STATUS: COMPLIANT - Default Users and Computers containers are properly redirected to deletion-protected Organizational Units." -ForegroundColor Green
        exit 0
    }

} catch {
    Write-Host "VULNERABLE: Failed to query Active Directory domain configuration. Error: $($_.Exception.Message)" -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Remediation (Set-DefaultContainersRedirection.ps1)</xhtml:h4>
        <xhtml:p>This script creates the target staging Organizational Units, enables accidental deletion protection, executes <xhtml:code>redircmp.exe</xhtml:code> and <xhtml:code>redirusr.exe</xhtml:code>, and verifies the updated well-known objects in Active Directory.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DefaultContainersRedirection.ps1">Download Script: Set-DefaultContainersRedirection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DefaultContainersRedirection.ps1
# Description: Creates staging OUs, configures accidental deletion protection,
#              and redirects default user and computer containers using redircmp and redirusr.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding(SupportsShouldProcess = $true)]
param (
    [Parameter(Mandatory = $false)]
    [string]$TargetComputersOUName = "Staging-Computers",

    [Parameter(Mandatory = $false)]
    [string]$TargetUsersOUName = "Staging-Users",

    [Parameter(Mandatory = $false)]
    [string]$ParentOUPath
)

Write-Host "--- Applying Hardening: Redirect Default Users and Computers Containers ---" -ForegroundColor Cyan

# 1. Verify Active Directory module availability
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    exit 1
}

Import-Module ActiveDirectory

try {
    $domain = Get-ADDomain -ErrorAction Stop
    $domainDN = $domain.DistinguishedName

    # Determine base path
    if ([string]::IsNullOrEmpty($ParentOUPath)) {
        $basePath = $domainDN
    } else {
        $basePath = $ParentOUPath
    }

    $targetComputersDN = "OU=$($TargetComputersOUName),$($basePath)"
    $targetUsersDN = "OU=$($TargetUsersOUName),$($basePath)"

    Write-Host "[i] Target Computers OU DN: $($targetComputersDN)" -ForegroundColor Gray
    Write-Host "[i] Target Users OU DN    : $($targetUsersDN)" -ForegroundColor Gray
    Write-Host ""

    # -------------------------------------------------------------
    # 2. Provision and Protect Computers Staging OU
    # -------------------------------------------------------------
    $existingCompOU = Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($targetComputersDN)'" -ErrorAction SilentlyContinue
    if ($null -eq $existingCompOU) {
        if ($PSCmdlet.ShouldProcess($targetComputersDN, "Create Organizational Unit and enable Accidental Deletion Protection")) {
            Write-Host "[+] Creating target Computers OU: $($targetComputersDN)" -ForegroundColor Yellow
            New-ADOrganizationalUnit -Name $TargetComputersOUName -Path $basePath -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Target Computers OU created and protected successfully." -ForegroundColor Green
        }
    } else {
        Write-Host "[+] Target Computers OU already exists. Ensuring accidental deletion protection is enabled..." -ForegroundColor Yellow
        if ($PSCmdlet.ShouldProcess($targetComputersDN, "Set ProtectedFromAccidentalDeletion = $true")) {
            Set-ADOrganizationalUnit -Identity $targetComputersDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Accidental deletion protection verified on Computers OU." -ForegroundColor Green
        }
    }

    # -------------------------------------------------------------
    # 3. Provision and Protect Users Staging OU
    # -------------------------------------------------------------
    $existingUserOU = Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($targetUsersDN)'" -ErrorAction SilentlyContinue
    if ($null -eq $existingUserOU) {
        if ($PSCmdlet.ShouldProcess($targetUsersDN, "Create Organizational Unit and enable Accidental Deletion Protection")) {
            Write-Host "[+] Creating target Users OU: $($targetUsersDN)" -ForegroundColor Yellow
            New-ADOrganizationalUnit -Name $TargetUsersOUName -Path $basePath -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Target Users OU created and protected successfully." -ForegroundColor Green
        }
    } else {
        Write-Host "[+] Target Users OU already exists. Ensuring accidental deletion protection is enabled..." -ForegroundColor Yellow
        if ($PSCmdlet.ShouldProcess($targetUsersDN, "Set ProtectedFromAccidentalDeletion = $true")) {
            Set-ADOrganizationalUnit -Identity $targetUsersDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Accidental deletion protection verified on Users OU." -ForegroundColor Green
        }
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 4. Redirect Computers Container via redircmp.exe
    # -------------------------------------------------------------
    if ($domain.ComputersContainer -ne $targetComputersDN) {
        if ($PSCmdlet.ShouldProcess($domainDN, "Redirect Computers Container to $($targetComputersDN)")) {
            Write-Host "[+] Redirecting default Computers container to: $($targetComputersDN)..." -ForegroundColor Yellow
            $outputComp = &amp; redircmp.exe $targetComputersDN 2&gt;&amp;1
            if ($LASTEXITCODE -eq 0) {
                Write-Host "[+] redircmp output: $($outputComp)" -ForegroundColor Green
            } else {
                throw "redircmp.exe failed with exit code $($LASTEXITCODE). Output: $($outputComp)"
            }
        }
    } else {
        Write-Host "[+] Computers container is already redirected to target OU: $($targetComputersDN)" -ForegroundColor Green
    }

    # -------------------------------------------------------------
    # 5. Redirect Users Container via redirusr.exe
    # -------------------------------------------------------------
    if ($domain.UsersContainer -ne $targetUsersDN) {
        if ($PSCmdlet.ShouldProcess($domainDN, "Redirect Users Container to $($targetUsersDN)")) {
            Write-Host "[+] Redirecting default Users container to: $($targetUsersDN)..." -ForegroundColor Yellow
            $outputUser = &amp; redirusr.exe $targetUsersDN 2&gt;&amp;1
            if ($LASTEXITCODE -eq 0) {
                Write-Host "[+] redirusr output: $($outputUser)" -ForegroundColor Green
            } else {
                throw "redirusr.exe failed with exit code $($LASTEXITCODE). Output: $($outputUser)"
            }
        }
    } else {
        Write-Host "[+] Users container is already redirected to target OU: $($targetUsersDN)" -ForegroundColor Green
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 6. Post-Remediation Verification
    # -------------------------------------------------------------
    $refreshedDomain = Get-ADDomain -ErrorAction Stop
    Write-Host "Post-Remediation Verification:" -ForegroundColor Cyan
    Write-Host "  - Domain ComputersContainer: $($refreshedDomain.ComputersContainer)" -ForegroundColor Gray
    Write-Host "  - Domain UsersContainer    : $($refreshedDomain.UsersContainer)" -ForegroundColor Gray

    if ($refreshedDomain.ComputersContainer -eq $targetComputersDN -and $refreshedDomain.UsersContainer -eq $targetUsersDN) {
        Write-Host "`n[+] Default containers redirection completed successfully." -ForegroundColor Green
    } else {
        Write-Warning "Directory attributes have not yet reflected the redirection. Allow time for domain-wide replication."
    }

    Write-Host ""
    Write-Host "[IMPORTANT NEXT STEPS]:" -ForegroundColor Yellow
    Write-Host "1. Link a quarantine/staging Group Policy Object (GPO) to '$($targetComputersDN)' (enforcing LAPS, Firewall, Credential Guard)." -ForegroundColor Gray
    Write-Host "2. Delegate 'Create Computer Objects' on '$($targetComputersDN)' to authorized provisioning service accounts." -ForegroundColor Gray
    Write-Host "3. Inventory and migrate any non-built-in residual accounts from 'CN=Computers' and 'CN=Users' to appropriate production OUs." -ForegroundColor Gray

} catch {
    Write-Error "Remediation failed. Error: $($_.Exception.Message)"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DefaultContainersRedirection.ps1
# Description: Creates staging OUs, configures accidental deletion protection,
#              and redirects default user and computer containers using redircmp and redirusr.
# Target Engine: Windows PowerShell 5.1

[CmdletBinding(SupportsShouldProcess = $true)]
param (
    [Parameter(Mandatory = $false)]
    [string]$TargetComputersOUName = "Staging-Computers",

    [Parameter(Mandatory = $false)]
    [string]$TargetUsersOUName = "Staging-Users",

    [Parameter(Mandatory = $false)]
    [string]$ParentOUPath
)

Write-Host "--- Applying Hardening: Redirect Default Users and Computers Containers ---" -ForegroundColor Cyan

# 1. Verify Active Directory module availability
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    Write-Error "The ActiveDirectory PowerShell module is required to execute this script."
    exit 1
}

Import-Module ActiveDirectory

try {
    $domain = Get-ADDomain -ErrorAction Stop
    $domainDN = $domain.DistinguishedName

    # Determine base path
    if ([string]::IsNullOrEmpty($ParentOUPath)) {
        $basePath = $domainDN
    } else {
        $basePath = $ParentOUPath
    }

    $targetComputersDN = "OU=$($TargetComputersOUName),$($basePath)"
    $targetUsersDN = "OU=$($TargetUsersOUName),$($basePath)"

    Write-Host "[i] Target Computers OU DN: $($targetComputersDN)" -ForegroundColor Gray
    Write-Host "[i] Target Users OU DN    : $($targetUsersDN)" -ForegroundColor Gray
    Write-Host ""

    # -------------------------------------------------------------
    # 2. Provision and Protect Computers Staging OU
    # -------------------------------------------------------------
    $existingCompOU = Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($targetComputersDN)'" -ErrorAction SilentlyContinue
    if ($null -eq $existingCompOU) {
        if ($PSCmdlet.ShouldProcess($targetComputersDN, "Create Organizational Unit and enable Accidental Deletion Protection")) {
            Write-Host "[+] Creating target Computers OU: $($targetComputersDN)" -ForegroundColor Yellow
            New-ADOrganizationalUnit -Name $TargetComputersOUName -Path $basePath -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Target Computers OU created and protected successfully." -ForegroundColor Green
        }
    } else {
        Write-Host "[+] Target Computers OU already exists. Ensuring accidental deletion protection is enabled..." -ForegroundColor Yellow
        if ($PSCmdlet.ShouldProcess($targetComputersDN, "Set ProtectedFromAccidentalDeletion = $true")) {
            Set-ADOrganizationalUnit -Identity $targetComputersDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Accidental deletion protection verified on Computers OU." -ForegroundColor Green
        }
    }

    # -------------------------------------------------------------
    # 3. Provision and Protect Users Staging OU
    # -------------------------------------------------------------
    $existingUserOU = Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($targetUsersDN)'" -ErrorAction SilentlyContinue
    if ($null -eq $existingUserOU) {
        if ($PSCmdlet.ShouldProcess($targetUsersDN, "Create Organizational Unit and enable Accidental Deletion Protection")) {
            Write-Host "[+] Creating target Users OU: $($targetUsersDN)" -ForegroundColor Yellow
            New-ADOrganizationalUnit -Name $TargetUsersOUName -Path $basePath -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Target Users OU created and protected successfully." -ForegroundColor Green
        }
    } else {
        Write-Host "[+] Target Users OU already exists. Ensuring accidental deletion protection is enabled..." -ForegroundColor Yellow
        if ($PSCmdlet.ShouldProcess($targetUsersDN, "Set ProtectedFromAccidentalDeletion = $true")) {
            Set-ADOrganizationalUnit -Identity $targetUsersDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop
            Write-Host "[+] Accidental deletion protection verified on Users OU." -ForegroundColor Green
        }
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 4. Redirect Computers Container via redircmp.exe
    # -------------------------------------------------------------
    if ($domain.ComputersContainer -ne $targetComputersDN) {
        if ($PSCmdlet.ShouldProcess($domainDN, "Redirect Computers Container to $($targetComputersDN)")) {
            Write-Host "[+] Redirecting default Computers container to: $($targetComputersDN)..." -ForegroundColor Yellow
            $outputComp = &amp; redircmp.exe $targetComputersDN 2&gt;&amp;1
            if ($LASTEXITCODE -eq 0) {
                Write-Host "[+] redircmp output: $($outputComp)" -ForegroundColor Green
            } else {
                throw "redircmp.exe failed with exit code $($LASTEXITCODE). Output: $($outputComp)"
            }
        }
    } else {
        Write-Host "[+] Computers container is already redirected to target OU: $($targetComputersDN)" -ForegroundColor Green
    }

    # -------------------------------------------------------------
    # 5. Redirect Users Container via redirusr.exe
    # -------------------------------------------------------------
    if ($domain.UsersContainer -ne $targetUsersDN) {
        if ($PSCmdlet.ShouldProcess($domainDN, "Redirect Users Container to $($targetUsersDN)")) {
            Write-Host "[+] Redirecting default Users container to: $($targetUsersDN)..." -ForegroundColor Yellow
            $outputUser = &amp; redirusr.exe $targetUsersDN 2&gt;&amp;1
            if ($LASTEXITCODE -eq 0) {
                Write-Host "[+] redirusr output: $($outputUser)" -ForegroundColor Green
            } else {
                throw "redirusr.exe failed with exit code $($LASTEXITCODE). Output: $($outputUser)"
            }
        }
    } else {
        Write-Host "[+] Users container is already redirected to target OU: $($targetUsersDN)" -ForegroundColor Green
    }

    Write-Host ""

    # -------------------------------------------------------------
    # 6. Post-Remediation Verification
    # -------------------------------------------------------------
    $refreshedDomain = Get-ADDomain -ErrorAction Stop
    Write-Host "Post-Remediation Verification:" -ForegroundColor Cyan
    Write-Host "  - Domain ComputersContainer: $($refreshedDomain.ComputersContainer)" -ForegroundColor Gray
    Write-Host "  - Domain UsersContainer    : $($refreshedDomain.UsersContainer)" -ForegroundColor Gray

    if ($refreshedDomain.ComputersContainer -eq $targetComputersDN -and $refreshedDomain.UsersContainer -eq $targetUsersDN) {
        Write-Host "`n[+] Default containers redirection completed successfully." -ForegroundColor Green
    } else {
        Write-Warning "Directory attributes have not yet reflected the redirection. Allow time for domain-wide replication."
    }

    Write-Host ""
    Write-Host "[IMPORTANT NEXT STEPS]:" -ForegroundColor Yellow
    Write-Host "1. Link a quarantine/staging Group Policy Object (GPO) to '$($targetComputersDN)' (enforcing LAPS, Firewall, Credential Guard)." -ForegroundColor Gray
    Write-Host "2. Delegate 'Create Computer Objects' on '$($targetComputersDN)' to authorized provisioning service accounts." -ForegroundColor Gray
    Write-Host "3. Inventory and migrate any non-built-in residual accounts from 'CN=Computers' and 'CN=Users' to appropriate production OUs." -ForegroundColor Gray

} catch {
    Write-Error "Remediation failed. Error: $($_.Exception.Message)"
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-007" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-007] Mandate Naming Conventions for GPOs, OUs, and User Accounts</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Services (Logical Structure), Management Stations, Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016+, Windows 10 Enterprise, Windows 11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/mandate-naming-conventions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory environments, particularly those with administrative tiering, require strict logical organization to maintain security boundaries and prevent operational errors. The lack of standard naming conventions leads to several security and operational risks: 1. <xhtml:strong>Administrative Confusions and Misconfigurations</xhtml:strong>: Without clear identifiers, administrators might link a highly restrictive Tier 0 GPO to a Tier 2 Client Workstations OU, causing system outages or security bypasses. 2. <xhtml:strong>Audit and Monitoring Gaps</xhtml:strong>: Security monitoring tools and SIEM parsers rely on predictable account and resource patterns (such as <xhtml:code>a0-</xhtml:code> for Tier 0 admin actions) to flag abnormal logons or lateral movement attempts. 3. <xhtml:strong>Privilege Escalation</xhtml:strong>: Predictable naming conventions for standard accounts, combined with clear tier prefixes for administrative accounts, prevent users from mistakenly allocating administrative permissions to non-admin accounts. 4. <xhtml:strong>Configuration Drift</xhtml:strong>: Group Policy Objects without descriptions or identifiers become "orphaned" or modified by different teams without clear change tracking, leading to undocumented changes that weaken the security posture.</xhtml:p>
        <xhtml:p>Enforcing structured GPO, OU, and Account naming conventions, combined with a mandatory description template for GPOs, establishes self-documenting metadata that can be programmatically audited to ensure long-term directory integrity.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Logical Configuration (GUI)</xhtml:h3>
        <xhtml:h4>1. Organizational Unit (OU) Hierarchy Design</xhtml:h4>
        <xhtml:p>Establish a clear, tiered OU hierarchy in <xhtml:strong>Active Directory Users and Computers</xhtml:strong> (<xhtml:code>dsa.msc</xhtml:code>). All custom OUs must follow the format: <xhtml:code>&lt;Tier&gt;-&lt;ObjectType&gt;-&lt;Function&gt;</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Tier</xhtml:em>
          <xhtml:em>: `T0` (Tier 0), `T1` (Tier 1), `T2` (Tier 2), or `Global` (common infrastructure/domain-wide settings). </xhtml:em>
          <xhtml:strong>ObjectType</xhtml:strong>: <xhtml:code>Computers</xhtml:code>, <xhtml:code>Users</xhtml:code>, <xhtml:code>Groups</xhtml:code>, or <xhtml:code>ServiceAccounts</xhtml:code>. <xhtml:em> </xhtml:em>
          <xhtml:em>Function</xhtml:em>*: Descriptive PascalCase text indicating the target scope.</xhtml:p>
        <xhtml:p>Examples of compliant OUs: <xhtml:em> `T0-Computers-DomainControllers` (for DCs) </xhtml:em>
          <xhtml:code>T1-Computers-ApplicationServers</xhtml:code> (for Tier 1 member servers) <xhtml:em> `T2-Computers-Workstations` (for Tier 2 client computers) </xhtml:em>
          <xhtml:code>T0-Users-Admins</xhtml:code> (for Tier 0 administrative users) * <xhtml:code>T1-Users-ServiceAccounts</xhtml:code> (for Tier 1 application/service accounts)</xhtml:p>
        <xhtml:h4>2. Group Policy Object (GPO) Naming Scheme</xhtml:h4>
        <xhtml:p>Create GPOs in the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) using the following naming structure: <xhtml:code>GPO_&lt;Scope&gt;_&lt;Class&gt;_&lt;Name&gt;</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Scope</xhtml:em>
          <xhtml:em>: `T0` (Tier 0), `T1` (Tier 1), `T2` (Tier 2), or `Global` (domain-wide). </xhtml:em>
          <xhtml:strong>Class</xhtml:strong>: <xhtml:code>Hardening</xhtml:code> (security settings), <xhtml:code>Config</xhtml:code> (operational settings), <xhtml:code>Restricted</xhtml:code> (restricted logons/groups), or <xhtml:code>Software</xhtml:code> (installations). <xhtml:em> </xhtml:em>
          <xhtml:em>Name</xhtml:em>*: Descriptive PascalCase text indicating policy focus.</xhtml:p>
        <xhtml:p>Examples of compliant GPOs: <xhtml:em> `GPO_T0_Hardening_DomainControllers` </xhtml:em>
          <xhtml:code>GPO_T2_Config_WorkstationIsolation</xhtml:code> * <xhtml:code>GPO_Global_Hardening_DefaultDomain</xhtml:code>
        </xhtml:p>
        <xhtml:h4>3. GPO Description Metadata Template</xhtml:h4>
        <xhtml:p>Every GPO must have its <xhtml:strong>Description</xhtml:strong> field populated in <xhtml:code>gpmc.msc</xhtml:code> properties using the following structured template. This template uses a YAML-compatible layout to support programmatic validation:</xhtml:p>
        <xhtml:pre>
          <xhtml:code>---
RequirementID: [ID of corresponding hardening control, e.g., REQ-OPS-007]
Owner: [Administrative team/role responsible, e.g., Domain Admins]
CreatedBy: [Account name of creator, e.g., a0-sysadmin]
CreatedDate: [YYYY-MM-DD]
LastModifiedBy: [Account name of editor, e.g., a0-sysadmin]
LastModifiedDate: [YYYY-MM-DD]
Purpose: [A clear, concise summary of the settings applied and their intent]
ApprovalRef: [Change management ticket or authorization reference, e.g., CR-84920]
Tier: [T0 / T1 / T2 / Global]
---</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>4. Active Directory Account Naming Scheme</xhtml:h4>
        <xhtml:p>Configure and provision accounts using standardized prefixes: <xhtml:em> </xhtml:em>
          <xhtml:em>Tier 0 Administrative Accounts</xhtml:em>
          <xhtml:em>: Prefix `a0-` (e.g., `a0-florian`). </xhtml:em>
          <xhtml:strong>Tier 1 Administrative Accounts</xhtml:strong>: Prefix <xhtml:code>a1-</xhtml:code> (e.g., <xhtml:code>a1-florian</xhtml:code>). <xhtml:em> </xhtml:em>
          <xhtml:em>Tier 2 Administrative Accounts</xhtml:em>
          <xhtml:em>: Prefix `a2-` (e.g., `a2-florian`). </xhtml:em>
          <xhtml:strong>Tier 0 Service Accounts / gMSAs</xhtml:strong>: Prefix <xhtml:code>s0-</xhtml:code> / <xhtml:code>g0-</xhtml:code> (e.g., <xhtml:code>s0-backup</xhtml:code>, <xhtml:code>g0-adbackup$</xhtml:code>). <xhtml:em> </xhtml:em>
          <xhtml:em>Tier 1 Service Accounts / gMSAs</xhtml:em>
          <xhtml:em>: Prefix `s1-` / `g1-` (e.g., `s1-sql`, `g1-sqlservice$`). </xhtml:em>
          <xhtml:strong>Tier 2 Service Accounts / gMSAs</xhtml:strong>: Prefix <xhtml:code>s2-</xhtml:code> / <xhtml:code>g2-</xhtml:code> (e.g., <xhtml:code>s2-print</xhtml:code>, <xhtml:code>g2-printservice$</xhtml:code>). <xhtml:em> </xhtml:em>
          <xhtml:em>Emergency (Break-Glass) Accounts</xhtml:em>*: Prefix <xhtml:code>bg-</xhtml:code> (e.g., <xhtml:code>bg-admin1</xhtml:code>).</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Administrative Scripting (Remediation / Auditing)</xhtml:h3>
        <xhtml:h4>1. Configuring GPO Description Metadata</xhtml:h4>
        <xhtml:p>Use the following remediation script to programmatically write or update the structured metadata template to a specified GPO's description field.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-GPODescription.ps1">Download Script: Configure-GPODescription.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-GPODescription.ps1
# Description: Configures structured metadata in a GPO's description field.

param (
    [Parameter(Mandatory = $true)]
    [string]$GPOName,

    [Parameter(Mandatory = $true)]
    [string]$RequirementID,

    [Parameter(Mandatory = $true)]
    [string]$Owner,

    [Parameter(Mandatory = $true)]
    [string]$CreatedBy,

    [Parameter(Mandatory = $true)]
    [string]$ApprovalRef,

    [Parameter(Mandatory = $true)]
    [ValidateSet("T0", "T1", "T2", "Global")]
    [string]$Tier,

    [Parameter(Mandatory = $true)]
    [string]$Purpose
)

Import-Module GroupPolicy -ErrorAction SilentlyContinue

Write-Host "--- Configuring Structured GPO Description Metadata ---" -ForegroundColor Cyan

# Verify if GPO exists
$gpo = Get-GPO -Name $GPOName -ErrorAction SilentlyContinue
if (-not $gpo) {
    Write-Error "Group Policy Object '$GPOName' was not found in the domain."
    exit 1
}

$CurrentDate = Get-Date -Format "yyyy-MM-dd"

# Build YAML-style metadata string
$DescriptionText = @"
---
RequirementID: $RequirementID
Owner: $Owner
CreatedBy: $CreatedBy
CreatedDate: $CurrentDate
LastModifiedBy: $CreatedBy
LastModifiedDate: $CurrentDate
Purpose: $Purpose
ApprovalRef: $ApprovalRef
Tier: $Tier
---
"@

try {
    # Set the GPO description
    Set-GPO -Name $GPOName -Description $DescriptionText -ErrorAction Stop
    Write-Host "[+] Successfully configured description metadata for GPO: $GPOName" -ForegroundColor Green
    exit 0
} catch {
    Write-Error "Failed to update description for GPO '$GPOName'. Error: $($_.Exception.Message)"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify directory alignment and find non-compliant OUs, GPOs, and Accounts:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-NamingConventions.ps1">Download Script: Audit-NamingConventions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-NamingConventions.ps1
# Description: Audits GPOs, OUs, and User Accounts for compliance with standard naming conventions and metadata description templates.

Import-Module ActiveDirectory -ErrorAction SilentlyContinue
Import-Module GroupPolicy -ErrorAction SilentlyContinue

Write-Host "--- Auditing Active Directory Naming Conventions &amp; Metadata ---" -ForegroundColor Cyan

$Compliant = $true

# Define Regex Patterns
$gpoNameRegex = "^GPO_(T[0-2]|Global)_(Hardening|Config|Restricted|Software)_[A-Za-z0-9]+$"
$ouNameRegex  = "^(T[0-2]-(Computers|Users|Groups|ServiceAccounts|Servers|Endpoints|Admins)-[A-Za-z0-9-]+|Domain Controllers|System|Builtin|ForeignSecurityPrincipals|LostAndFound|NTDS Quotas|Program Data)$"

# 1. Audit GPO Names and Description Fields
Write-Host "`n[+] Checking Group Policy Objects..." -ForegroundColor Yellow
try {
    $gpos = Get-GPO -All -ErrorAction Stop
    foreach ($gpo in $gpos) {
        $gpoName = $gpo.DisplayName
        
        # Check Name format
        if ($gpoName -notmatch $gpoNameRegex) {
            Write-Host "  [-] NON-COMPLIANT GPO NAME: '$gpoName' (does not match expected structure)" -ForegroundColor Red
            $Compliant = $false
        } else {
            Write-Host "  [+] GPO Name OK: '$gpoName'" -ForegroundColor Green
        }

        # Check Description metadata
        $desc = $gpo.Description
        if ([string]::IsNullOrEmpty($desc)) {
            Write-Host "  [-] NON-COMPLIANT GPO DESCRIPTION: '$gpoName' (Description field is empty)" -ForegroundColor Red
            $Compliant = $false
        } else {
            # Verify YAML structure has key metadata fields
            $hasReqId = $desc -match "RequirementID:"
            $hasOwner = $desc -match "Owner:"
            $hasTier  = $desc -match "Tier:"
            $hasPurpose = $desc -match "Purpose:"

            if ($hasReqId -and $hasOwner -and $hasTier -and $hasPurpose) {
                Write-Host "  [+] GPO Description Template OK: '$gpoName'" -ForegroundColor Green
            } else {
                Write-Host "  [-] NON-COMPLIANT GPO DESCRIPTION FORMAT: '$gpoName' (Structured fields are missing or malformed)" -ForegroundColor Red
                $Compliant = $false
            }
        }
    }
} catch {
    Write-Warning "Could not retrieve GPOs from domain. Ensure GPMC RSAT tools are installed and domain is reachable."
}

# 2. Audit Organizational Units
Write-Host "`n[+] Checking Organizational Units (OUs)..." -ForegroundColor Yellow
try {
    $ous = Get-ADOrganizationalUnit -Filter * -ErrorAction Stop
    foreach ($ou in $ous) {
        $ouName = $ou.Name
        if ($ouName -notmatch $ouNameRegex) {
            Write-Host "  [-] NON-COMPLIANT OU NAME: '$ouName' (DistinguishedName: $($ou.DistinguishedName))" -ForegroundColor Red
            $Compliant = $false
        } else {
            Write-Host "  [+] OU Name OK: '$ouName'" -ForegroundColor Green
        }
    }
} catch {
    Write-Warning "Could not retrieve OUs from Active Directory. Ensure AD RSAT tools are installed."
}

# 3. Audit Account Naming Conventions (Tiered / Service / Emergency)
Write-Host "`n[+] Checking Account Naming Conventions..." -ForegroundColor Yellow
try {
    # Check Administrative Group memberships to see if administrative accounts are properly prefixed
    $privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")
    foreach ($group in $privilegedGroups) {
        $members = Get-ADGroupMember -Identity $group -ErrorAction SilentlyContinue
        foreach ($member in $members) {
            if ($member.objectClass -eq "user") {
                $sam = $member.SamAccountName
                # Tier 0 admins must have 'a0-' or 'bg-' or be standard default Administrator
                if ($sam -ne "Administrator" -and $sam -notlike "a0-*" -and $sam -notlike "bg-*") {
                    Write-Host "  [-] NON-COMPLIANT TIER 0 ACCOUNT NAME: '$sam' (Member of privileged group: $group, lacks 'a0-' or 'bg-' prefix)" -ForegroundColor Red
                    $Compliant = $false
                } else {
                    Write-Host "  [+] Admin Account Prefix OK: '$sam' ($group)" -ForegroundColor Green
                }
            }
        }
    }
    
    # Audit Service Accounts and gMSAs
    $serviceAccounts = Get-ADServiceAccount -Filter * -ErrorAction SilentlyContinue
    foreach ($sa in $serviceAccounts) {
        $sam = $sa.SamAccountName
        if ($sam -notlike "g0-*" -and $sam -notlike "g1-*" -and $sam -notlike "g2-*") {
            Write-Host "  [-] NON-COMPLIANT gMSA NAME: '$sam' (lacks 'g0-', 'g1-', or 'g2-' prefix)" -ForegroundColor Red
            $Compliant = $false
        } else {
            Write-Host "  [+] gMSA Prefix OK: '$sam'" -ForegroundColor Green
        }
    }
} catch {
    Write-Warning "Could not query account or group memberships. Ensure AD RSAT tools are installed and domain is reachable."
}

# 4. Final Compliance Verdict
if ($Compliant) {
    Write-Host "`nStatus: Compliant. GPOs, OUs, and Accounts conform to standard conventions." -ForegroundColor Green
    exit 0
} else {
    Write-Host "`nStatus: Non-Compliant. Naming conventions drift detected." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-GPODescription.ps1
# Description: Configures structured metadata in a GPO's description field.

param (
    [Parameter(Mandatory = $true)]
    [string]$GPOName,

    [Parameter(Mandatory = $true)]
    [string]$RequirementID,

    [Parameter(Mandatory = $true)]
    [string]$Owner,

    [Parameter(Mandatory = $true)]
    [string]$CreatedBy,

    [Parameter(Mandatory = $true)]
    [string]$ApprovalRef,

    [Parameter(Mandatory = $true)]
    [ValidateSet("T0", "T1", "T2", "Global")]
    [string]$Tier,

    [Parameter(Mandatory = $true)]
    [string]$Purpose
)

Import-Module GroupPolicy -ErrorAction SilentlyContinue

Write-Host "--- Configuring Structured GPO Description Metadata ---" -ForegroundColor Cyan

# Verify if GPO exists
$gpo = Get-GPO -Name $GPOName -ErrorAction SilentlyContinue
if (-not $gpo) {
    Write-Error "Group Policy Object '$GPOName' was not found in the domain."
    exit 1
}

$CurrentDate = Get-Date -Format "yyyy-MM-dd"

# Build YAML-style metadata string
$DescriptionText = @"
---
RequirementID: $RequirementID
Owner: $Owner
CreatedBy: $CreatedBy
CreatedDate: $CurrentDate
LastModifiedBy: $CreatedBy
LastModifiedDate: $CurrentDate
Purpose: $Purpose
ApprovalRef: $ApprovalRef
Tier: $Tier
---
"@

try {
    # Set the GPO description
    Set-GPO -Name $GPOName -Description $DescriptionText -ErrorAction Stop
    Write-Host "[+] Successfully configured description metadata for GPO: $GPOName" -ForegroundColor Green
    exit 0
} catch {
    Write-Error "Failed to update description for GPO '$GPOName'. Error: $($_.Exception.Message)"
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6007" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-008" severity="high" weight="10.0" selected="false">
      <title>[REQ-OPS-008] Configure Daily System State Backups</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/configure-system-state-backups.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Disaster Recovery is a core pillar of Active Directory security. If Domain Controllers are corrupted or compromised, administrators must recover from trusted, clean states.</xhtml:p>
        <xhtml:p>The System State contains the Active Directory database (ntds.dit), the SYSVOL share, registry settings, certificates, and DNS records.</xhtml:p>
        <xhtml:p>To ensure resilience: 1. <xhtml:strong>Daily Frequency</xhtml:strong>: Create System State Backups daily on at least two Domain Controllers to minimize data loss. 2. <xhtml:strong>Storage Isolation (Offline/Immutable)</xhtml:strong>: Backups must be stored on separate physical or virtual storage. In high-security systems, enforce write-once-read-many (WORM) storage or store backups in an offline, physically secured media rotation to prevent modifications by compromised accounts. 3. <xhtml:strong>Regular Validation</xhtml:strong>: Run recovery exercises quarterly in an isolated network sandbox to verify that restored DCs are functional and free of replication loops.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Graphical User Interface (GUI) Configuration</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Log in to the Domain Controller and open <xhtml:strong>Server Manager</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Manage</xhtml:strong> -&gt; <xhtml:strong>Add Roles and Features</xhtml:strong>.</xhtml:li>
          <xhtml:li>Advance to the <xhtml:strong>Features</xhtml:strong> step, check <xhtml:strong>Windows Server Backup</xhtml:strong>, and complete the installation.</xhtml:li>
          <xhtml:li>Open the administrative tool <xhtml:strong>Windows Server Backup</xhtml:strong> (wbadmin.msc).</xhtml:li>
          <xhtml:li>In the Actions pane, click <xhtml:strong>Backup Schedule...</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the Backup Schedule Wizard, click <xhtml:strong>Next</xhtml:strong> on the Getting Started page.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Custom</xhtml:strong> configuration and click <xhtml:strong>Next</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Add Items</xhtml:strong>, check <xhtml:strong>System State</xhtml:strong>, and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Specify the time and frequency (once a day, during off-peak hours) and click <xhtml:strong>Next</xhtml:strong>.</xhtml:li>
          <xhtml:li>Choose the destination type (dedicated backup disk, volume, or shared network folder) and complete the wizard.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to install the Windows Server Backup feature, configure a System State backup policy, and execute an immediate System State backup to a designated disk volume.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-ADSystemStateBackup.ps1">Download Script: Set-ADSystemStateBackup.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-ADSystemStateBackup.ps1
# Installs Windows Server Backup and executes a System State backup.

Write-Host "--- Initializing System State Backup ---" -ForegroundColor Cyan

# 1. Install Windows Server Backup feature if missing
$feature = Get-WindowsFeature -Name Windows-Server-Backup
if ($feature.Installed -eq $false) {
    Write-Host "[+] Installing Windows Server Backup feature..." -ForegroundColor Gray
    Install-WindowsFeature -Name Windows-Server-Backup -IncludeAllSubFeature | Out-Null
    Write-Host "    Feature installed successfully." -ForegroundColor Green
} else {
    Write-Host "[+] Windows Server Backup feature is already installed." -ForegroundColor Green
}

# Import WSB module
Import-Module WindowsServerBackup

# 2. Define Backup Volume Target
$BackupVolumePath = "E:\" # Replace with your designated offline backup storage disk
if (-not (Test-Path $BackupVolumePath)) {
    Write-Error "Backup target volume '$BackupVolumePath' does not exist. Please specify a valid volume."
    exit 1
}

# 3. Create Backup Policy
Write-Host "[+] Configuring System State Backup Policy..." -ForegroundColor Gray
$policy = New-WBPolicy
Add-WBSystemState -Policy $policy | Out-Null

$backupTarget = New-WBBackupTarget -VolumePath $BackupVolumePath
Add-WBBackupTarget -Policy $policy -Target $backupTarget | Out-Null

Write-Host "    Backup Policy created (Target: $BackupVolumePath, Subject: SystemState)." -ForegroundColor Green

# 4. Execute Backup Job
Write-Host "[+] Starting System State Backup. This process can take several minutes..." -ForegroundColor Yellow
$backupJob = Start-WBBackup -Policy $policy -Async

# Monitor backup job status
while ($backupJob.State -eq "Running" -or $backupJob.State -eq "Verifying") {
    Write-Host "    - Backup Progress: $($backupJob.PercentComplete)% complete..." -ForegroundColor Gray
    Start-Sleep -Seconds 10
    # Refresh backup job status
    $backupJob = Get-WBJob
}

# Final output
$finalJob = Get-WBJob -Previous 1
if ($finalJob.JobState -eq "Completed") {
    Write-Host "`nSystem State Backup Completed successfully!" -ForegroundColor Green
} else {
    Write-Error "`nBackup failed with status: $($finalJob.JobState). Error: $($finalJob.ErrorDescription)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify active backup configurations:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-ADBackupStatus.ps1">Download Script: Audit-ADBackupStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-ADBackupStatus.ps1
# Audits the status of local system state backups.

Import-Module WindowsServerBackup -ErrorAction SilentlyContinue

Write-Host "--- Auditing System State Backup Status ---" -ForegroundColor Cyan

# Check if Windows Server Backup feature is installed
$feature = Get-WindowsFeature -Name Windows-Server-Backup -ErrorAction SilentlyContinue
if ($feature -and $feature.Installed -eq $false) {
    Write-Warning "Windows Server Backup feature is NOT installed on this machine."
    exit 1
}

# Retrieve history of local backups
try {
    $backups = Get-WBBackupSet -ErrorAction Stop
    Write-Host "`n[+] Found $($backups.Count) recorded backup sets." -ForegroundColor Yellow
    
    # Sort and output the most recent backups
    $sortedBackups = $backups | Sort-Object -Property BackupTime -Descending
    foreach ($bk in $sortedBackups | Select-Object -First 5) {
        $containsSystemState = $bk.CatalogFlags -match "SystemState"
        $statusColor = if ($containsSystemState) { "Green" } else { "Yellow" }
        Write-Host "    - Backup Time: $($bk.BackupTime) | Location: $($bk.VolumePath) | Contains SystemState: $containsSystemState" -ForegroundColor $statusColor
    }
} catch {
    Write-Host "[-] No backup records found on the system. System state backups may not be configured." -ForegroundColor Red
}

# Audit Backup Target Access Control List
$policy = Get-WBPolicy -ErrorAction SilentlyContinue
if ($policy) {
    $targets = Get-WBBackupTarget -Policy $policy -ErrorAction SilentlyContinue
    foreach ($target in $targets) {
        $path = $null
        if ($target.VolumePath) {
            $path = $target.VolumePath
        } elseif ($target.NetworkPath) {
            $path = $target.NetworkPath
        }
        
        if ($path) {
            Write-Host "`n[*] Auditing backup target permissions: $path" -ForegroundColor Gray
            if (Test-Path $path) {
                $acl = Get-Acl -Path $path -ErrorAction SilentlyContinue
                if ($acl) {
                    $unauthorized = $false
                    foreach ($access in $acl.Access) {
                        $identity = $access.IdentityReference.Value
                        $rights = $access.FileSystemRights
                        $type = $access.AccessControlType
                        
                        if ($type -eq "Allow") {
                            if ($identity -notmatch "SYSTEM|Administrators|Domain Admins|Enterprise Admins|Creator Owner|NT AUTHORITY\\SYSTEM|BUILTIN\\Administrators") {
                                if ($rights -match "Read|Write|Modify|FullControl") {
                                    Write-Host "    [!] WARNING: Unauthorized identity '$identity' has '$rights' access to backup target." -ForegroundColor Red
                                    $unauthorized = $true
                                }
                            }
                        }
                    }
                    if (-not $unauthorized) {
                        Write-Host "    [+] Target directory ACL is securely restricted." -ForegroundColor Green
                    }
                } else {
                    Write-Warning "    Could not retrieve ACL for backup target."
                }
            } else {
                Write-Host "    [-] Backup target path is currently offline or unreachable." -ForegroundColor Yellow
            }
        }
    }
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-ADSystemStateBackup.ps1
# Installs Windows Server Backup and executes a System State backup.

Write-Host "--- Initializing System State Backup ---" -ForegroundColor Cyan

# 1. Install Windows Server Backup feature if missing
$feature = Get-WindowsFeature -Name Windows-Server-Backup
if ($feature.Installed -eq $false) {
    Write-Host "[+] Installing Windows Server Backup feature..." -ForegroundColor Gray
    Install-WindowsFeature -Name Windows-Server-Backup -IncludeAllSubFeature | Out-Null
    Write-Host "    Feature installed successfully." -ForegroundColor Green
} else {
    Write-Host "[+] Windows Server Backup feature is already installed." -ForegroundColor Green
}

# Import WSB module
Import-Module WindowsServerBackup

# 2. Define Backup Volume Target
$BackupVolumePath = "E:\" # Replace with your designated offline backup storage disk
if (-not (Test-Path $BackupVolumePath)) {
    Write-Error "Backup target volume '$BackupVolumePath' does not exist. Please specify a valid volume."
    exit 1
}

# 3. Create Backup Policy
Write-Host "[+] Configuring System State Backup Policy..." -ForegroundColor Gray
$policy = New-WBPolicy
Add-WBSystemState -Policy $policy | Out-Null

$backupTarget = New-WBBackupTarget -VolumePath $BackupVolumePath
Add-WBBackupTarget -Policy $policy -Target $backupTarget | Out-Null

Write-Host "    Backup Policy created (Target: $BackupVolumePath, Subject: SystemState)." -ForegroundColor Green

# 4. Execute Backup Job
Write-Host "[+] Starting System State Backup. This process can take several minutes..." -ForegroundColor Yellow
$backupJob = Start-WBBackup -Policy $policy -Async

# Monitor backup job status
while ($backupJob.State -eq "Running" -or $backupJob.State -eq "Verifying") {
    Write-Host "    - Backup Progress: $($backupJob.PercentComplete)% complete..." -ForegroundColor Gray
    Start-Sleep -Seconds 10
    # Refresh backup job status
    $backupJob = Get-WBJob
}

# Final output
$finalJob = Get-WBJob -Previous 1
if ($finalJob.JobState -eq "Completed") {
    Write-Host "`nSystem State Backup Completed successfully!" -ForegroundColor Green
} else {
    Write-Error "`nBackup failed with status: $($finalJob.JobState). Error: $($finalJob.ErrorDescription)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6008" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-009" severity="high" weight="10.0" selected="false">
      <title>[REQ-OPS-009] Implement Offline Patch Management via WSUS</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Dedicated WSUS Update Servers (Tier 0 &amp; Tier 1/2)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/implement-offline-patch-management.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Keeping Domain Controllers, member servers, and clients patched is critical to resolve OS and RPC vulnerabilities. In isolated, air-gapped networks, direct connection to Microsoft Update servers is impossible, requiring all patches to be imported offline.</xhtml:p>
        <xhtml:p>Establishing an offline WSUS sync protocol: 1. <xhtml:strong>Prevents Network exposure</xhtml:strong>: Domain Controllers and administrative hosts do not require access to external network zones. 2. <xhtml:strong>Maintains Integrity</xhtml:strong>: Allows checking update metadata and approvals in a controlled sandbox environment before propagating them to production. 3. <xhtml:strong>Automates Distribution</xhtml:strong>: Uses standard WSUS client policies to distribute approved updates locally with minimal network overhead.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>WSUS Categories &amp; Classifications Configuration</xhtml:h3>
        <xhtml:p>Before performing the import/export process, both the online (source) and offline (destination) WSUS servers must be configured with identical Products and Classifications. If the destination server does not have the corresponding categories enabled, the imported update metadata for those categories will be ignored.</xhtml:p>
        <xhtml:h4>1. Graphical User Interface (GUI) Configuration</xhtml:h4>
        <xhtml:p>On both the online and offline WSUS administration consoles: 1. Open the <xhtml:strong>Windows Server Update Services</xhtml:strong> console (<xhtml:code>wsus.msc</xhtml:code>). 2. Expand the server name and click on <xhtml:strong>Options</xhtml:strong> -&gt; <xhtml:strong>Products and Classifications</xhtml:strong>. 3. In the <xhtml:strong>Products</xhtml:strong> tab, ensure the exact operating systems present in the environment are selected: <xhtml:em> </xhtml:em>
          <xhtml:em>Windows Server 2016</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Windows Server 2019</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Windows Server 2022</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Windows 10</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Windows 11</xhtml:em>
          <xhtml:em> 4. In the </xhtml:em>
          <xhtml:em>Classifications</xhtml:em>
          <xhtml:em> tab, ensure the following classifications are selected: </xhtml:em>
          <xhtml:strong>Critical Updates</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Security Updates</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Definition Updates</xhtml:strong> (mandatory if distributing Windows Defender signatures) <xhtml:em> </xhtml:em>
          <xhtml:em>Update Rollups</xhtml:em>
          <xhtml:em> (standard cumulative updates) 5. Click </xhtml:em>
          <xhtml:em>Apply</xhtml:em>
          <xhtml:em> and then click </xhtml:em>
          <xhtml:em>OK</xhtml:em>*.</xhtml:p>
        <xhtml:h4>2. PowerShell Configuration</xhtml:h4>
        <xhtml:p>Run the following PowerShell commands as Administrator on both WSUS servers to align Categories and Classifications programmatically:</xhtml:p>
        <xhtml:pre>
          <xhtml:code># Import WSUS module
Import-Module UpdateServices

Write-Host "--- Aligning WSUS Categories &amp; Classifications ---" -ForegroundColor Cyan

# Define targets
$TargetClassifications = @("Critical Updates", "Security Updates", "Definition Updates", "Update Rollups")
$TargetProducts = @("Windows Server 2016", "Windows Server 2019", "Windows Server 2022", "Windows 10", "Windows 11")

# Enable Classifications
Write-Host "[+] Configuring WSUS Classifications..." -ForegroundColor Gray
Get-WsusClassification | Where-Object { $TargetClassifications -contains $_.Classification.Title } | Set-WsusClassification

# Enable Products
Write-Host "[+] Configuring WSUS Products..." -ForegroundColor Gray
Get-WsusProduct | Where-Object { $TargetProducts -contains $_.Product.Title } | Set-WsusProduct

Write-Host "[+] WSUS categories and classifications updated successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option A: Command-line Execution (wsusutil)</xhtml:h3>
        <xhtml:h4>1. On the Internet-Connected WSUS Server</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Wait for standard synchronization to complete, or force a sync.</xhtml:li>
          <xhtml:li>Open a Command Prompt as Administrator.</xhtml:li>
          <xhtml:li>Export the WSUS metadata file:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>wsusutil.exe export C:\export\metadata.xml.gz C:\export\export.log</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the metadata file (<xhtml:code>metadata.xml.gz</xhtml:code>) and the entire <xhtml:code>WSUSContent</xhtml:code> directory (containing the update binaries) onto an encrypted and scanned storage medium.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. On the Air-Gapped WSUS Server</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Connect the transfer storage medium and copy the files to a local staging directory (e.g., <xhtml:code>C:\import</xhtml:code>).</xhtml:li>
          <xhtml:li>Open a Command Prompt as Administrator.</xhtml:li>
          <xhtml:li>Import the update metadata:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>wsusutil.exe import C:\import\metadata.xml.gz C:\import\import.log</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the update binary files from the storage medium into the WSUS content directory of the air-gapped server.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use the following PowerShell script to programmatically import WSUS metadata from a specified location using the native WSUS utility.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Invoke-OfflineWsusImport.ps1">Download Script: Invoke-OfflineWsusImport.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Invoke-OfflineWsusImport.ps1
# Description: Imports WSUS update metadata from an offline backup file.

param (
    [Parameter(Mandatory = $true)]
    [string]$MetadataPath,
    
    [Parameter(Mandatory = $true)]
    [string]$LogPath
)

Write-Host "--- Performing Offline WSUS Import ---" -ForegroundColor Cyan

if (-not (Test-Path $MetadataPath)) {
    Write-Error "Metadata file not found at: $MetadataPath"
    exit 1
}

# Run wsusutil import
$WsusUtil = "C:\Program Files\Update Services\Tools\wsusutil.exe"
if (-not (Test-Path $WsusUtil)) {
    Write-Error "wsusutil.exe not found at default location."
    exit 1
}

Write-Host "[+] Running wsusutil import..." -ForegroundColor Yellow
$Process = Start-Process -FilePath $WsusUtil -ArgumentList "import `"$MetadataPath`" `"$LogPath`"" -Wait -NoNewWindow -PassThru

if ($Process.ExitCode -eq 0) {
    Write-Host "[+] Offline WSUS Import completed successfully." -ForegroundColor Green
} else {
    Write-Error "wsusutil import failed with exit code $($Process.ExitCode)."
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify synchronization state of the local WSUS server:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-OfflineWsusSyncStatus.ps1">Download Script: Get-OfflineWsusSyncStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-OfflineWsusSyncStatus.ps1
# Description: Checks the synchronization history of the local WSUS server.

Import-Module UpdateServices -ErrorAction SilentlyContinue

Write-Host "--- Auditing WSUS Offline Synchronization Status ---" -ForegroundColor Cyan

try {
    # Connect to the local WSUS server
    $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()
    $history = $wsus.GetSubscription().GetSynchronizationHistory()
    
    if ($history.Count -gt 0) {
        $lastSync = $history[0]
        Write-Host "[+] Last WSUS Sync Time: $($lastSync.EndTime)" -ForegroundColor Green
        Write-Host "[+] Last WSUS Sync Result: $($lastSync.Result)" -ForegroundColor Green
        if ($lastSync.Result -eq "Succeeded") {
            exit 0
        } else {
            Write-Warning "Last WSUS Sync did not succeed."
            exit 1
        }
    } else {
        Write-Host "[-] No WSUS synchronization history found." -ForegroundColor Red
        exit 1
    }
} catch {
    Write-Host "[-] Failed to retrieve WSUS synchronization history. Ensure the WSUS role is installed and services are running." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Invoke-OfflineWsusImport.ps1
# Description: Imports WSUS update metadata from an offline backup file.

param (
    [Parameter(Mandatory = $true)]
    [string]$MetadataPath,
    
    [Parameter(Mandatory = $true)]
    [string]$LogPath
)

Write-Host "--- Performing Offline WSUS Import ---" -ForegroundColor Cyan

if (-not (Test-Path $MetadataPath)) {
    Write-Error "Metadata file not found at: $MetadataPath"
    exit 1
}

# Run wsusutil import
$WsusUtil = "C:\Program Files\Update Services\Tools\wsusutil.exe"
if (-not (Test-Path $WsusUtil)) {
    Write-Error "wsusutil.exe not found at default location."
    exit 1
}

Write-Host "[+] Running wsusutil import..." -ForegroundColor Yellow
$Process = Start-Process -FilePath $WsusUtil -ArgumentList "import `"$MetadataPath`" `"$LogPath`"" -Wait -NoNewWindow -PassThru

if ($Process.ExitCode -eq 0) {
    Write-Host "[+] Offline WSUS Import completed successfully." -ForegroundColor Green
} else {
    Write-Error "wsusutil import failed with exit code $($Process.ExitCode)."
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6009" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-010" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-010] Establish Continuous Security Assessments</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory Domain Services, Management Workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016+, Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/establish-continuous-security-assessments.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory configurations naturally drift over time as a result of administrative changes, new trust relationships, and changing group policies. Administrators must actively search for misconfigurations, weak permissions, and signs of compromise.</xhtml:p>
        <xhtml:p>In isolated, air-gapped networks, online security analysis services cannot be reached. Therefore: 1. <xhtml:strong>Periodic Scans</xhtml:strong>: Execute security audits locally using offline-compatible tools (such as PingCastle, BloodHound/SharpHound, Locksmith, or ORADAD). 2. <xhtml:strong>Directory Health Monitoring</xhtml:strong>: Run PingCastle monthly to generate local XML/HTML reports indicating domain vulnerabilities and tracking AD configuration health. 3. <xhtml:strong>Lateral Movement Auditing</xhtml:strong>: Execute SharpHound quarterly to construct lateral movement path graphs, enabling defenders to identify complex trust relationships or delegation chains leading to Tier 0 compromise. 4. <xhtml:strong>Active Directory Certificate Services Auditing</xhtml:strong>: Run Locksmith monthly to identify misconfigured certificate templates, insecure enrollment settings, and potential AD CS privilege escalation paths. 5. <xhtml:strong>Data Isolation</xhtml:strong>: Transfer the diagnostic reports, CSV exports, and export ZIPs out of production to secure, offline assessment platforms to limit exposure of sensitive configuration data.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Diagnostic Tool Execution</xhtml:h3>
        <xhtml:h4>1. Running PingCastle Audits</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Place <xhtml:code>PingCastle.exe</xhtml:code> in a secure local diagnostic directory (e.g., <xhtml:code>C:\Diagnostics</xhtml:code>).</xhtml:li>
          <xhtml:li>Open a Command Prompt as Administrator on a domain-joined workstation.</xhtml:li>
          <xhtml:li>Run the following command to generate the HTML report and XML output:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>PingCastle.exe --server target.domain.local --level level_Default --xml --no_update</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Collect the generated files from the directory and transfer them to a secure analysis terminal.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Running BloodHound/SharpHound Collectors</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Place the <xhtml:code>SharpHound.exe</xhtml:code> collector binary in the diagnostic directory.</xhtml:li>
          <xhtml:li>Open a Command Prompt as Administrator on a domain-joined workstation.</xhtml:li>
          <xhtml:li>Run the collector using standard active directory enumeration methods:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`cmd</xhtml:li>
          <xhtml:li>SharpHound.exe --CollectionMethods All --Domain target.domain.local --ZipFileName AD_BloodHound_Export.zip</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the resulting zip file to the offline BloodHound graph database dashboard to query and audit lateral movement paths.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>3. Running Locksmith Audits (AD CS)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Download the <xhtml:code>Invoke-Locksmith.ps1</xhtml:code> script from the official repository and place it in the diagnostic directory (e.g., <xhtml:code>C:\Diagnostics</xhtml:code>).</xhtml:li>
          <xhtml:li>Open PowerShell as Administrator on a domain-joined workstation.</xhtml:li>
          <xhtml:li>Run the script using the CSV export mode (Mode 2) to audit AD CS and save findings:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`powershell</xhtml:li>
          <xhtml:li>Set-Location -Path C:\Diagnostics</xhtml:li>
          <xhtml:li>.\Invoke-Locksmith.ps1 -Mode 2</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the generated <xhtml:code>ADCSIssues.CSV</xhtml:code> report to a secure analysis terminal for offline review.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use the following PowerShell script to automate the execution of PingCastle, SharpHound, and Locksmith collectors inside a specified diagnostic workspace.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Start-OfflineAssessments.ps1">Download Script: Start-OfflineAssessments.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Start-OfflineAssessments.ps1
# Description: Triggers PingCastle, SharpHound, and Locksmith security audit scans.

param (
    [string]$DiagnosticsPath = "C:\Diagnostics",
    [string]$DomainName = "target.domain.local"
)

Write-Host "--- Starting AD Hardening Offline Assessment Scans ---" -ForegroundColor Cyan

if (-not (Test-Path $DiagnosticsPath)) {
    New-Item -Path $DiagnosticsPath -ItemType Directory -Force | Out-Null
}

$PingCastlePath = Join-Path $DiagnosticsPath "PingCastle.exe"
$SharpHoundPath = Join-Path $DiagnosticsPath "SharpHound.exe"
$LocksmithPath = Join-Path $DiagnosticsPath "Invoke-Locksmith.ps1"

# 1. Execute PingCastle
if (Test-Path $PingCastlePath) {
    Write-Host "[+] Executing PingCastle..." -ForegroundColor Yellow
    $params = @(
        "--server", $DomainName,
        "--level", "level_Default",
        "--xml",
        "--no_update",
        "--output", $DiagnosticsPath
    )
    Start-Process -FilePath $PingCastlePath -ArgumentList $params -Wait -NoNewWindow
    Write-Host "[+] PingCastle scan complete." -ForegroundColor Green
} else {
    Write-Error "PingCastle.exe not found at $PingCastlePath. Please place the binary to execute."
}

# 2. Execute SharpHound
if (Test-Path $SharpHoundPath) {
    Write-Host "[+] Executing SharpHound..." -ForegroundColor Yellow
    $zipName = "AD_BloodHound_Export_" + (Get-Date -Format "yyyyMMdd") + ".zip"
    $zipPath = Join-Path $DiagnosticsPath $zipName
    
    $params = @(
        "--CollectionMethods", "All",
        "--Domain", $DomainName,
        "--ZipFileName", $zipPath
    )
    Start-Process -FilePath $SharpHoundPath -ArgumentList $params -Wait -NoNewWindow
    Write-Host "[+] SharpHound collection complete. Saved to: $zipPath" -ForegroundColor Green
} else {
    Write-Error "SharpHound.exe not found at $SharpHoundPath. Please place the binary to execute."
}

# 3. Execute Locksmith
if (Test-Path $LocksmithPath) {
    Write-Host "[+] Executing Locksmith..." -ForegroundColor Yellow
    $originalLocation = Get-Location
    Set-Location -Path $DiagnosticsPath
    try {
        &amp; $LocksmithPath -Mode 2
        Write-Host ("[+] Locksmith scan complete. Saved to: " + (Join-Path $DiagnosticsPath "ADCSIssues.CSV")) -ForegroundColor Green
    }
    catch {
        Write-Error "Failed to execute Locksmith: $($_.Exception.Message)"
    }
    finally {
        Set-Location -Path $originalLocation
    }
} else {
    Write-Error "Invoke-Locksmith.ps1 not found at $LocksmithPath. Please place the script to execute."
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that diagnostic tools and recent reports exist on the auditing system:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-OfflineAssessmentStatus.ps1">Download Script: Get-OfflineAssessmentStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-OfflineAssessmentStatus.ps1
# Description: Audits the presence of PingCastle, SharpHound, and Locksmith tools and the age of recent reports.

Write-Host "--- Auditing Active Directory Security Assessment Tools ---" -ForegroundColor Cyan

$DiagnosticsPath = "C:\Diagnostics" # Common diagnostics path
$PingCastlePath = Join-Path $DiagnosticsPath "PingCastle.exe"
$SharpHoundPath = Join-Path $DiagnosticsPath "SharpHound.exe"
$LocksmithPath = Join-Path $DiagnosticsPath "Invoke-Locksmith.ps1"
$ReportAgeDays = 30

$Compliant = $true

# 1. Check PingCastle
if (Test-Path $PingCastlePath) {
    Write-Host "[+] PingCastle executable found: $PingCastlePath" -ForegroundColor Green
    
    # Check if reports have been generated in the last 30 days
    $reports = Get-ChildItem -Path $DiagnosticsPath -Filter "*pingcastle*.xml" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge (Get-Date).AddDays(-$ReportAgeDays) }
    if ($reports) {
        Write-Host "    [+] Found $($reports.Count) recent PingCastle report(s) (within last $ReportAgeDays days)." -ForegroundColor Green
    } else {
        Write-Warning "    [-] No recent PingCastle report found (older than $ReportAgeDays days)."
        $Compliant = $false
    }
} else {
    Write-Warning "[-] PingCastle executable NOT found at: $PingCastlePath"
    $Compliant = $false
}

# 2. Check SharpHound
if (Test-Path $SharpHoundPath) {
    Write-Host "[+] SharpHound executable found: $SharpHoundPath" -ForegroundColor Green
    
    # Check if data exports exist
    $exports = Get-ChildItem -Path $DiagnosticsPath -Filter "*BloodHound*.zip" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge (Get-Date).AddDays(-$ReportAgeDays) }
    if ($exports) {
        Write-Host "    [+] Found $($exports.Count) recent SharpHound export(s) (within last $ReportAgeDays days)." -ForegroundColor Green
    } else {
        Write-Warning "    [-] No recent SharpHound export found (older than $ReportAgeDays days)."
        $Compliant = $false
    }
} else {
    Write-Warning "[-] SharpHound executable NOT found at: $SharpHoundPath"
    $Compliant = $false
}

# 3. Check Locksmith
if (Test-Path $LocksmithPath) {
    Write-Host "[+] Locksmith script found: $LocksmithPath" -ForegroundColor Green
    
    # Check if Locksmith CSV output exists and was generated in the last 30 days
    $locksmithReport = Get-ChildItem -Path $DiagnosticsPath -Filter "ADCSIssues.CSV" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge (Get-Date).AddDays(-$ReportAgeDays) }
    if ($locksmithReport) {
        Write-Host "    [+] Found recent Locksmith report (within last $ReportAgeDays days)." -ForegroundColor Green
    } else {
        Write-Warning "    [-] No recent Locksmith report (ADCSIssues.CSV) found (older than $ReportAgeDays days)."
        $Compliant = $false
    }
} else {
    Write-Warning "[-] Locksmith script (Invoke-Locksmith.ps1) NOT found at: $LocksmithPath"
    $Compliant = $false
}

if ($Compliant) {
    Write-Host "`nStatus: Compliant. Diagnostics tools and recent reports are present." -ForegroundColor Green
    exit 0
} else {
    Write-Host "`nStatus: Non-Compliant. Action required." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Start-OfflineAssessments.ps1
# Description: Triggers PingCastle, SharpHound, and Locksmith security audit scans.

param (
    [string]$DiagnosticsPath = "C:\Diagnostics",
    [string]$DomainName = "target.domain.local"
)

Write-Host "--- Starting AD Hardening Offline Assessment Scans ---" -ForegroundColor Cyan

if (-not (Test-Path $DiagnosticsPath)) {
    New-Item -Path $DiagnosticsPath -ItemType Directory -Force | Out-Null
}

$PingCastlePath = Join-Path $DiagnosticsPath "PingCastle.exe"
$SharpHoundPath = Join-Path $DiagnosticsPath "SharpHound.exe"
$LocksmithPath = Join-Path $DiagnosticsPath "Invoke-Locksmith.ps1"

# 1. Execute PingCastle
if (Test-Path $PingCastlePath) {
    Write-Host "[+] Executing PingCastle..." -ForegroundColor Yellow
    $params = @(
        "--server", $DomainName,
        "--level", "level_Default",
        "--xml",
        "--no_update",
        "--output", $DiagnosticsPath
    )
    Start-Process -FilePath $PingCastlePath -ArgumentList $params -Wait -NoNewWindow
    Write-Host "[+] PingCastle scan complete." -ForegroundColor Green
} else {
    Write-Error "PingCastle.exe not found at $PingCastlePath. Please place the binary to execute."
}

# 2. Execute SharpHound
if (Test-Path $SharpHoundPath) {
    Write-Host "[+] Executing SharpHound..." -ForegroundColor Yellow
    $zipName = "AD_BloodHound_Export_" + (Get-Date -Format "yyyyMMdd") + ".zip"
    $zipPath = Join-Path $DiagnosticsPath $zipName
    
    $params = @(
        "--CollectionMethods", "All",
        "--Domain", $DomainName,
        "--ZipFileName", $zipPath
    )
    Start-Process -FilePath $SharpHoundPath -ArgumentList $params -Wait -NoNewWindow
    Write-Host "[+] SharpHound collection complete. Saved to: $zipPath" -ForegroundColor Green
} else {
    Write-Error "SharpHound.exe not found at $SharpHoundPath. Please place the binary to execute."
}

# 3. Execute Locksmith
if (Test-Path $LocksmithPath) {
    Write-Host "[+] Executing Locksmith..." -ForegroundColor Yellow
    $originalLocation = Get-Location
    Set-Location -Path $DiagnosticsPath
    try {
        &amp; $LocksmithPath -Mode 2
        Write-Host ("[+] Locksmith scan complete. Saved to: " + (Join-Path $DiagnosticsPath "ADCSIssues.CSV")) -ForegroundColor Green
    }
    catch {
        Write-Error "Failed to execute Locksmith: $($_.Exception.Message)"
    }
    finally {
        Set-Location -Path $originalLocation
    }
} else {
    Write-Error "Invoke-Locksmith.ps1 not found at $LocksmithPath. Please place the script to execute."
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-011" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-011] Enable Detailed BSOD Stop Parameters for Crash Control</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers, Tier 2 Client Workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 10, Windows 11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/enable-detailed-bsod-parameters.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>During critical system failures (such as a kernel panic or Blue Screen of Death - BSOD), Windows by default displays a simplified error screen intended for general consumers, hiding the actual bugcheck code and parameters.</xhtml:p>
        <xhtml:p>Enabling detailed stop error parameters is crucial because: 1. <xhtml:strong>Offline Diagnostics</xhtml:strong>: In air-gapped, isolated environments, administrators cannot easily query online resources, transmit automated memory dumps, or contact cloud support. 2. <xhtml:strong>Immediate Visibility</xhtml:strong>: Having the exact stop code (e.g., <xhtml:code>0x0000000A</xhtml:code>) and the four parameters visible on the screen or virtual console allows operators to diagnose driver, memory, or hardware issues immediately. 3. <xhtml:strong>Improves Mean Time to Recovery (MTTR)</xhtml:strong>: Speeds up troubleshooting during disaster recovery or critical server restore processes.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration</xhtml:h3>
        <xhtml:p>Because this parameter resides in the system registry and is not exposed as a default administrative template, it must be deployed via Group Policy Preferences (GPP):</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management station.</xhtml:li>
          <xhtml:li>Create a new GPO targeting all domain computers (e.g., <xhtml:code>GPO_Global_Config_SystemHardening</xhtml:code>) or edit an existing policy.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click the <xhtml:strong>Registry</xhtml:strong> node and select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: Update</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\CrashControl</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>DisplayParameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the top-level OU structure containing computers, servers, and Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script block to enable detailed stop error parameters locally in the registry.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-CrashControl.ps1">Download Script: Set-CrashControl.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-CrashControl.ps1
# Description: Enables detailed BSOD parameters in the registry.

Write-Host "--- Configuring Detailed BSOD Parameters ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

Set-ItemProperty -Path $Path -Name "DisplayParameters" -Value 1 -Type DWord -Force | Out-Null
Write-Host "[+] Detailed BSOD stop parameters configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that detailed stop parameters are enabled:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-CrashControl.ps1">Download Script: Audit-CrashControl.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-CrashControl.ps1
# Description: Audits whether detailed BSOD parameters are enabled in the registry.

Write-Host "--- Auditing Detailed BSOD Parameters ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl"
if (Test-Path $Path) {
    $Val = Get-ItemProperty -Path $Path -Name "DisplayParameters" -ErrorAction SilentlyContinue
    if ($Val -and $Val.DisplayParameters -eq 1) {
        Write-Host "[+] Detailed BSOD stop parameters are ENABLED (Compliant)." -ForegroundColor Green
    } else {
        Write-Host "[-] Detailed BSOD stop parameters are DISABLED (Non-Compliant)." -ForegroundColor Red
        exit 1
    }
} else {
    Write-Host "[-] Registry path HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl not found." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-CrashControl.ps1
# Description: Enables detailed BSOD parameters in the registry.

Write-Host "--- Configuring Detailed BSOD Parameters ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

Set-ItemProperty -Path $Path -Name "DisplayParameters" -Value 1 -Type DWord -Force | Out-Null
Write-Host "[+] Detailed BSOD stop parameters configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-012" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-012] Implement Automated Inactive Computer and User Account Cleanup</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Active Directory User and Computer Accounts (Tiers 0, 1, and 2).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Active Directory Domain Services (All supported functional levels).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/decommission-inactive-accounts.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Inactive computer and user accounts remain in the directory due to gaps in the employee offboarding or machine decommissioning processes.</xhtml:p>
        <xhtml:p>These stale accounts represent a significant security risk: 1. <xhtml:strong>Backdoor Persistence</xhtml:strong>: Attackers targeting a domain can take control of inactive accounts (especially stale administrative accounts or service accounts with never-expiring passwords) to establish persistent, quiet access that is rarely monitored. 2. <xhtml:strong>Resource-Based Delegation Exploits</xhtml:strong>: Stale computer accounts can be targeted by attackers to construct resource-based constrained delegation (RBCD) attacks, allowing them to impersonate high-privilege services and eventually compromise the domain. 3. <xhtml:strong>Password Aging bypass</xhtml:strong>: Standard computers automatically change their passwords every 30 days. If a machine is powered off or disconnected, its password age increases. If computer passwords are not rotated, or if a stale computer account remains enabled, it increases the risk of offline password dumping and hash-relay.</xhtml:p>
        <xhtml:p>Automatically disabling and isolating user accounts after 180 days of inactivity, and computer accounts after 90 days of inactivity, minimizes the active attack surface of the directory.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Scheduled Maintenance Task Setup</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Place the decommissioning script (<xhtml:code>Decommission-InactiveAccounts.ps1</xhtml:code>) in a secure administrative directory on a domain management host (e.g., <xhtml:code>C:\ADMaintenance\Scripts\</xhtml:code>).</xhtml:li>
          <xhtml:li>Open <xhtml:strong>Task Scheduler</xhtml:strong> (<xhtml:code>taskschd.msc</xhtml:code>) on the management host.</xhtml:li>
          <xhtml:li>Create a new task with the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account</xhtml:em>*: Run as a dedicated service account or <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code> (with delegated rights to modify user and computer accounts in target OUs).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Trigger</xhtml:em>*: Weekly (e.g., every Sunday at 02:00 AM).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: Start a program:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Program/script</xhtml:em>*: <xhtml:code>powershell.exe</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Arguments</xhtml:em>*: <xhtml:code>-NoProfile -ExecutionPolicy Bypass -File "C:\ADMaintenance\Scripts\Decommission-InactiveAccounts.ps1" -LogPath "C:\ADMaintenance\Logs\"</xhtml:code>
          </xhtml:li>
          <xhtml:li>Enable logging and monitor execution logs to verify that accounts are correctly identified, disabled, and moved to the Stale OU.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Active Directory Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>To automate the identification, disabling, and isolation of inactive accounts:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Decommission-InactiveAccounts.ps1">Download Script: Decommission-InactiveAccounts.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Decommission-InactiveAccounts.ps1
# Description: Disables and moves inactive user (180 days) and computer (90 days) accounts to a stale OU.

Import-Module ActiveDirectory

# Define thresholds
$UserInactivityDays = 180
$ComputerInactivityDays = 90

$UserCutoffDate = (Get-Date).AddDays(-$UserInactivityDays)
$ComputerCutoffDate = (Get-Date).AddDays(-$ComputerInactivityDays)

# Target OU for stale objects (adjust to your environment)
$StaleOU = "OU=StaleObjects,DC=domain,DC=local"
$Exclusions = @("Domain Controllers") # Exclude OUs containing DCs

if (-not (Get-ADOrganizationalUnit -Identity $StaleOU -ErrorAction SilentlyContinue)) {
    Write-Host "[-] Stale OU '$StaleOU' does not exist. Creating it." -ForegroundColor Yellow
    New-ADOrganizationalUnit -Name "StaleObjects" -Path (Get-ADDomain).DistinguishedName -Verbose
}

Write-Host "Scanning for inactive user accounts (no logon in last $UserInactivityDays days)..." -ForegroundColor Cyan
$StaleUsers = Get-ADUser -Filter {Enabled -eq $true -and LastLogonDate -lt $UserCutoffDate -and Name -ne "Administrator" -and Name -ne "Guest"} -Properties LastLogonDate

foreach ($user in $StaleUsers) {
    # Verify the user is not in excluded paths
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($user.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "Disabling and moving inactive user: $($user.SamAccountName) (Last Logon: $($user.LastLogonDate))" -ForegroundColor Yellow
    Set-ADUser -Identity $user -Enabled $false -Description "Disabled by AD Decommissioning Script - Inactive for $UserInactivityDays days"
    Move-ADObject -Identity $user -TargetPath $StaleOU
}

Write-Host "`nScanning for inactive computer accounts (no logon in last $ComputerInactivityDays days)..." -ForegroundColor Cyan
$StaleComputers = Get-ADComputer -Filter {Enabled -eq $true -and LastLogonDate -lt $ComputerCutoffDate} -Properties LastLogonDate

foreach ($comp in $StaleComputers) {
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($comp.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "Disabling and moving inactive computer: $($comp.Name) (Last Logon: $($comp.LastLogonDate))" -ForegroundColor Yellow
    Set-ADComputer -Identity $comp -Enabled $false -Description "Disabled by AD Decommissioning Script - Inactive for $ComputerInactivityDays days"
    Move-ADObject -Identity $comp -TargetPath $StaleOU
}

Write-Host "`nDecommissioning process completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the domain for stale user/computer accounts:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-InactiveAccountsStatus.ps1">Download Script: Get-InactiveAccountsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-InactiveAccountsStatus.ps1
# Audits the directory for enabled but inactive user (180 days) and computer (90 days) accounts.

Import-Module ActiveDirectory

$UserInactivityDays = 180
$ComputerInactivityDays = 90

$UserCutoffDate = (Get-Date).AddDays(-$UserInactivityDays)
$ComputerCutoffDate = (Get-Date).AddDays(-$ComputerInactivityDays)

$StaleUsers = Get-ADUser -Filter {Enabled -eq $true -and LastLogonDate -lt $UserCutoffDate -and Name -ne "Administrator" -and Name -ne "Guest"} -Properties LastLogonDate
$StaleComputers = Get-ADComputer -Filter {Enabled -eq $true -and LastLogonDate -lt $ComputerCutoffDate} -Properties LastLogonDate

$Exclusions = @("Domain Controllers")

$nonCompliantCount = 0

foreach ($user in $StaleUsers) {
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($user.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "[!] NON-COMPLIANT: User account '$($user.SamAccountName)' is enabled but inactive since $($user.LastLogonDate)" -ForegroundColor Red
    $nonCompliantCount++
}

foreach ($comp in $StaleComputers) {
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($comp.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "[!] NON-COMPLIANT: Computer account '$($comp.Name)' is enabled but inactive since $($comp.LastLogonDate)" -ForegroundColor Red
    $nonCompliantCount++
}

if ($nonCompliantCount -eq 0) {
    Write-Host "[+] COMPLIANT: No stale enabled user or computer accounts detected." -ForegroundColor Green
    exit 0
} else {
    Write-Host "[!] NON-COMPLIANT: Detected $nonCompliantCount stale enabled accounts that need to be decommissioned." -ForegroundColor Red
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Decommission-InactiveAccounts.ps1
# Description: Disables and moves inactive user (180 days) and computer (90 days) accounts to a stale OU.

Import-Module ActiveDirectory

# Define thresholds
$UserInactivityDays = 180
$ComputerInactivityDays = 90

$UserCutoffDate = (Get-Date).AddDays(-$UserInactivityDays)
$ComputerCutoffDate = (Get-Date).AddDays(-$ComputerInactivityDays)

# Target OU for stale objects (adjust to your environment)
$StaleOU = "OU=StaleObjects,DC=domain,DC=local"
$Exclusions = @("Domain Controllers") # Exclude OUs containing DCs

if (-not (Get-ADOrganizationalUnit -Identity $StaleOU -ErrorAction SilentlyContinue)) {
    Write-Host "[-] Stale OU '$StaleOU' does not exist. Creating it." -ForegroundColor Yellow
    New-ADOrganizationalUnit -Name "StaleObjects" -Path (Get-ADDomain).DistinguishedName -Verbose
}

Write-Host "Scanning for inactive user accounts (no logon in last $UserInactivityDays days)..." -ForegroundColor Cyan
$StaleUsers = Get-ADUser -Filter {Enabled -eq $true -and LastLogonDate -lt $UserCutoffDate -and Name -ne "Administrator" -and Name -ne "Guest"} -Properties LastLogonDate

foreach ($user in $StaleUsers) {
    # Verify the user is not in excluded paths
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($user.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "Disabling and moving inactive user: $($user.SamAccountName) (Last Logon: $($user.LastLogonDate))" -ForegroundColor Yellow
    Set-ADUser -Identity $user -Enabled $false -Description "Disabled by AD Decommissioning Script - Inactive for $UserInactivityDays days"
    Move-ADObject -Identity $user -TargetPath $StaleOU
}

Write-Host "`nScanning for inactive computer accounts (no logon in last $ComputerInactivityDays days)..." -ForegroundColor Cyan
$StaleComputers = Get-ADComputer -Filter {Enabled -eq $true -and LastLogonDate -lt $ComputerCutoffDate} -Properties LastLogonDate

foreach ($comp in $StaleComputers) {
    $isExcluded = $false
    foreach ($ex in $Exclusions) {
        if ($comp.DistinguishedName -like "*$ex*") { $isExcluded = $true }
    }
    if ($isExcluded) { continue }

    Write-Host "Disabling and moving inactive computer: $($comp.Name) (Last Logon: $($comp.LastLogonDate))" -ForegroundColor Yellow
    Set-ADComputer -Identity $comp -Enabled $false -Description "Disabled by AD Decommissioning Script - Inactive for $ComputerInactivityDays days"
    Move-ADObject -Identity $comp -TargetPath $StaleOU
}

Write-Host "`nDecommissioning process completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6012" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-OPS-013" severity="medium" weight="10.0" selected="false">
      <title>[REQ-OPS-013] Clean Up Staged Install From Media (IFM) Data</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Domain Controllers, Member Servers</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows Server 2016, Windows Server 2019, Windows Server 2022</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>06-operations-maintenance/cleanup-staged-ifm-files.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Install From Media (IFM) feature allows administrators to promote a new Domain Controller using an offline backup dataset rather than copying the entire Active Directory database over the network.</xhtml:p>
        <xhtml:p>To generate this dataset, administrators run the <xhtml:code>ntdsutil</xhtml:code> tool (e.g., <xhtml:code>ntdsutil "ac i ntds" "ifm" "create full c:\Staging" q q</xhtml:code>). This process generates a staging folder containing: 1. The Active Directory database file (<xhtml:code>ntds.dit</xhtml:code>). 2. Copies of the <xhtml:code>SYSTEM</xhtml:code> and <xhtml:code>SECURITY</xhtml:code> registry hives (which contain the boot key needed to decrypt the database file).</xhtml:p>
        <xhtml:p>If these staged IFM folders are left behind on member servers, administrative shares, or staging volumes, any user or attacker who compromises that machine can copy the files and extract all Active Directory password hashes offline. Securing active directory requires ensuring that temporary IFM datasets are deleted immediately after the new Domain Controller is promoted.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual Search and Deletion (GUI)</xhtml:h3>
        <xhtml:p>To manually locate and clean up staged IFM folders: 1. Log on to the staging Member Server or Domain Controller with administrative privileges. 2. Open <xhtml:strong>File Explorer</xhtml:strong> and search all local disk volumes (e.g., <xhtml:code>C:\</xhtml:code>, <xhtml:code>D:\</xhtml:code>) for files named <xhtml:code>ntds.dit</xhtml:code>. 3. Verify the location of each found file: <xhtml:em> </xhtml:em>
          <xhtml:em>Domain Controllers</xhtml:em>
          <xhtml:em>: The authorized directory is the Active Directory database path (typically `C:\Windows\NTDS\ntds.dit` as specified in the registry value `DSA Database file` under `HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters`). </xhtml:em>
          <xhtml:strong>Member Servers</xhtml:strong>: There are no authorized directories. Any instance of <xhtml:code>ntds.dit</xhtml:code> is unauthorized. 4. If an unauthorized <xhtml:code>ntds.dit</xhtml:code> file is located: <xhtml:em> Select the folder containing the `ntds.dit` file (which usually also contains a `registry` sub-folder). </xhtml:em> Delete the folder and clear it from the Recycle Bin.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Remediation (Non-GPO / Script-based)</xhtml:h3>
        <xhtml:p>Use these scripts to audit and automatically delete staged IFM datasets.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Remove-StagedIFM.ps1">Download Script: Remove-StagedIFM.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Remove-StagedIFM.ps1
# Description: Searches for unauthorized copies of ntds.dit and deletes them.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying hardening requirement: Clean Up Staged IFM Data..." -ForegroundColor Cyan

# 1. Resolve standard active directory database path (only applicable to DCs)
$StandardDir = $null
$StandardAdPath = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "DSA Database file" -ErrorAction SilentlyContinue)."DSA Database file"
if ($StandardAdPath) {
    $StandardDir = [System.IO.Path]::GetDirectoryName($StandardAdPath)
}

# 2. Recursive search function excluding standard heavy system directories
function Search-UnauthorizedDIT ($SearchPath) {
    if (-not (Test-Path $SearchPath)) { return @() }
    
    $Found = @()
    $Items = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue
    foreach ($Item in $Items) {
        if ($Item.Attributes -match "Directory") {
            # Skip system/program directories to optimize speed
            if ($Item.Name -match "^(Windows|Program Files|Program Files \(x86\)|\$Recycle\.Bin|System Volume Information|AppData)$") {
                continue
            }
            $Found += Search-UnauthorizedDIT $Item.FullName
        } elseif ($Item.Name -ieq "ntds.dit") {
            # Skip authorized DC database folder
            if ($null -ne $StandardDir -and $Item.DirectoryName -eq $StandardDir) {
                continue
            }
            $Found += $Item.FullName
        }
    }
    return $Found
}

# 3. Scan all local drives
$Drives = Get-PSDrive -PSProvider FileSystem
$VulnerableFiles = @()

foreach ($Drive in $Drives) {
    $Root = $Drive.Root
    Write-Host "[*] Scanning drive $Root for unauthorized ntds.dit files..." -ForegroundColor Gray
    $VulnerableFiles += Search-UnauthorizedDIT $Root
}

# 4. Delete unauthorized directories
if ($VulnerableFiles.Count -gt 0) {
    Write-Host "[-] Found $($VulnerableFiles.Count) unauthorized ntds.dit file(s)." -ForegroundColor Yellow
    foreach ($File in $VulnerableFiles) {
        $FolderToDelete = [System.IO.Path]::GetDirectoryName($File)
        Write-Host "[-] Deleting staging directory: $FolderToDelete" -ForegroundColor Yellow
        try {
            Remove-Item -Path $FolderToDelete -Recurse -Force -ErrorAction Stop
            Write-Host "[+] Directory $FolderToDelete successfully deleted." -ForegroundColor Green
        } catch {
            Write-Error "Failed to delete directory: $FolderToDelete. Error: $($_.Exception.Message)"
        }
    }
} else {
    Write-Host "[+] No unauthorized staged ntds.dit files found on local drives." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the system for staged IFM directories:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-StagedIFMStatus.ps1">Download Script: Get-StagedIFMStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-StagedIFMStatus.ps1
# Description: Audits local drives for unauthorized staged ntds.dit databases.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing Staged IFM Data ---" -ForegroundColor Cyan

# 1. Resolve standard active directory database path (only applicable to DCs)
$StandardDir = $null
$StandardAdPath = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "DSA Database file" -ErrorAction SilentlyContinue)."DSA Database file"
if ($StandardAdPath) {
    $StandardDir = [System.IO.Path]::GetDirectoryName($StandardAdPath)
}

# 2. Recursive search function
function Search-UnauthorizedDIT ($SearchPath) {
    if (-not (Test-Path $SearchPath)) { return @() }
    
    $Found = @()
    $Items = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue
    foreach ($Item in $Items) {
        if ($Item.Attributes -match "Directory") {
            # Skip system/program directories to optimize speed
            if ($Item.Name -match "^(Windows|Program Files|Program Files \(x86\)|\$Recycle\.Bin|System Volume Information|AppData)$") {
                continue
            }
            $Found += Search-UnauthorizedDIT $Item.FullName
        } elseif ($Item.Name -ieq "ntds.dit") {
            # Skip authorized DC database folder
            if ($null -ne $StandardDir -and $Item.DirectoryName -eq $StandardDir) {
                continue
            }
            $Found += $Item.FullName
        }
    }
    return $Found
}

# 3. Scan local drives
$Drives = Get-PSDrive -PSProvider FileSystem
$VulnerableFiles = @()

foreach ($Drive in $Drives) {
    $Root = $Drive.Root
    $VulnerableFiles += Search-UnauthorizedDIT $Root
}

# 4. Evaluate status
if ($VulnerableFiles.Count -gt 0) {
    foreach ($File in $VulnerableFiles) {
        Write-Host "[!] VULNERABLE: Unauthorized ntds.dit database found at: $File" -ForegroundColor Red
    }
    exit 1
} else {
    Write-Host "[+] Secure: No unauthorized staged ntds.dit database files found." -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Remove-StagedIFM.ps1
# Description: Searches for unauthorized copies of ntds.dit and deletes them.
# Target Engine: Windows PowerShell 5.1

Write-Host "Applying hardening requirement: Clean Up Staged IFM Data..." -ForegroundColor Cyan

# 1. Resolve standard active directory database path (only applicable to DCs)
$StandardDir = $null
$StandardAdPath = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "DSA Database file" -ErrorAction SilentlyContinue)."DSA Database file"
if ($StandardAdPath) {
    $StandardDir = [System.IO.Path]::GetDirectoryName($StandardAdPath)
}

# 2. Recursive search function excluding standard heavy system directories
function Search-UnauthorizedDIT ($SearchPath) {
    if (-not (Test-Path $SearchPath)) { return @() }
    
    $Found = @()
    $Items = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue
    foreach ($Item in $Items) {
        if ($Item.Attributes -match "Directory") {
            # Skip system/program directories to optimize speed
            if ($Item.Name -match "^(Windows|Program Files|Program Files \(x86\)|\$Recycle\.Bin|System Volume Information|AppData)$") {
                continue
            }
            $Found += Search-UnauthorizedDIT $Item.FullName
        } elseif ($Item.Name -ieq "ntds.dit") {
            # Skip authorized DC database folder
            if ($null -ne $StandardDir -and $Item.DirectoryName -eq $StandardDir) {
                continue
            }
            $Found += $Item.FullName
        }
    }
    return $Found
}

# 3. Scan all local drives
$Drives = Get-PSDrive -PSProvider FileSystem
$VulnerableFiles = @()

foreach ($Drive in $Drives) {
    $Root = $Drive.Root
    Write-Host "[*] Scanning drive $Root for unauthorized ntds.dit files..." -ForegroundColor Gray
    $VulnerableFiles += Search-UnauthorizedDIT $Root
}

# 4. Delete unauthorized directories
if ($VulnerableFiles.Count -gt 0) {
    Write-Host "[-] Found $($VulnerableFiles.Count) unauthorized ntds.dit file(s)." -ForegroundColor Yellow
    foreach ($File in $VulnerableFiles) {
        $FolderToDelete = [System.IO.Path]::GetDirectoryName($File)
        Write-Host "[-] Deleting staging directory: $FolderToDelete" -ForegroundColor Yellow
        try {
            Remove-Item -Path $FolderToDelete -Recurse -Force -ErrorAction Stop
            Write-Host "[+] Directory $FolderToDelete successfully deleted." -ForegroundColor Green
        } catch {
            Write-Error "Failed to delete directory: $FolderToDelete. Error: $($_.Exception.Message)"
        }
    }
} else {
    Write-Host "[+] No unauthorized staged ntds.dit files found on local drives." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:6013" />
      </check>
    </Rule>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening">
    <title>Module 7: Privileged Access Workstations (PAWs) Hardening</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-001] Configure AppLocker Policies for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-applocker-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) host highly sensitive Tier 0 credentials. If administrative workstations are allowed to execute arbitrary binaries, scripts, or installation packages, they become highly susceptible to malware infections, remote access trojans, and credential harvesting tools (like Mimikatz).</xhtml:p>
        <xhtml:p>Enforcing strict execution controls via AppLocker ensures that: 1. <xhtml:strong>Execution Control</xhtml:strong>: Only signed operating system files, approved software binaries, and scripts are allowed to execute. 2. <xhtml:strong>Standard User Restrictions</xhtml:strong>: Any standard users or unauthorized accounts cannot run executable files or installers from writeable directories (like <xhtml:code>%TEMP%</xhtml:code> or <xhtml:code>%USERPROFILE%</xhtml:code>). 3. <xhtml:strong>Defends Against AppLocker Bypasses</xhtml:strong>: Abusing trusted, signed Microsoft binaries (such as <xhtml:code>msbuild.exe</xhtml:code>, <xhtml:code>installutil.exe</xhtml:code>, <xhtml:code>regasm.exe</xhtml:code>, <xhtml:code>regsvcs.exe</xhtml:code>, <xhtml:code>mshta.exe</xhtml:code>, <xhtml:code>regsvr32.exe</xhtml:code>, <xhtml:code>rundll32.exe</xhtml:code>) allows attackers to execute arbitrary code bypassing default AppLocker rules. This control blocks these "Living off the Land" binaries (LOLBins) and prevents execution from user-writeable paths under <xhtml:code>%WINDIR%</xhtml:code> (such as <xhtml:code>Tasks</xhtml:code>, <xhtml:code>Temp</xhtml:code>, <xhtml:code>tracing</xhtml:code>, <xhtml:code>spool\drivers\color</xhtml:code>, etc.). 4. <xhtml:strong>Defense-in-Depth</xhtml:strong>: Even if an administrator is tricked into downloading a malicious file, AppLocker blocks the execution of the binary, preventing the compromise of the endpoint.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit the GPO linked to the PAWs Organizational Unit (OU) (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Application Control Policies\AppLocker</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure AppLocker Enforcement:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>AppLocker</xhtml:em>
            <xhtml:em> and select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> On the </xhtml:em>
            <xhtml:em>Enforcement</xhtml:em>
            <xhtml:em> tab, check </xhtml:em>
            <xhtml:em>Configured</xhtml:em>* under:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Executable rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Windows Installer rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Script rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Packaged app rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Executable Rules</xhtml:strong> and select <xhtml:strong>Create Default Rules</xhtml:strong> (this permits Windows files and program files).</xhtml:li>
          <xhtml:li>Delete the default rule allowing "Everyone" to run files in all locations, and replace it with a rule allowing only authorized administrative groups (e.g., <xhtml:code>Tier0-Admins</xhtml:code>) to run binaries outside the default system locations.</xhtml:li>
          <xhtml:li>Per <xhtml:strong>ANSSI R2</xhtml:strong> recommendation, do not create standalone Deny rules. Instead, configure the following path <xhtml:strong>Exceptions</xhtml:strong> on the default Allow rule for the Windows folder:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click the rule `(Default Rule) All files located in the Windows folder` and select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> On the </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for writeable directories under <xhtml:code>%WINDIR%</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Tasks\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Temp\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\tracing\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\spool\drivers\color\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> On the same </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for the following bypass binaries (LOLBins):</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msbuild.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\installutil.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mshta.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regasm.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvcs.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvr32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rundll32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\bginfo.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cdb.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cmstp.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\control.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\csi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dfsvc.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dnx.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\fsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ie4unit.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ieexec.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\infdefaultinstall.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mavinject.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdeploy.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdt.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msxsl.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\odbcconf.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\presentationhost.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rcsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\runscripthelper.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\te.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\tracker.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\xwizard.exe`</xhtml:li>
          <xhtml:li>Repeat the process for <xhtml:strong>Script Rules</xhtml:strong> by creating default rules and adding exceptions to the <xhtml:code>%WINDIR%\*</xhtml:code> Allow rule for script execution from user-writeable paths (such as <xhtml:code>%WINDIR%\Temp\*</xhtml:code> and <xhtml:code>%WINDIR%\Tasks\*</xhtml:code>).</xhtml:li>
          <xhtml:li>Disable NTVDM (16-bit application support) to prevent AppLocker bypasses via 16-bit binaries:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\16-bit Application Compatibility</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Configure </xhtml:em>
            <xhtml:em>Prevent access to 16-bit applications</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Link the GPO to the PAWs Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the Application Identity service (<xhtml:code>AppIDSvc</xhtml:code>) and import the robust AppLocker policy locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawAppLockerService.ps1">Download Script: Configure-PawAppLockerService.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAppLockerService.ps1
# Description: Configures the Application Identity service (AppIDSvc) to start automatically and imports a robust AppLocker XML policy.

Write-Host "Applying AppLocker Identity service hardening..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$AppLockerService = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($AppLockerService) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    Start-Service -Name AppIDSvc -ErrorAction SilentlyContinue
    Write-Host "[+] Application Identity Service (AppIDSvc) set to Automatic and started." -ForegroundColor Green
} else {
    Write-Warning "[-] Application Identity Service not found on this machine."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerPawPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the AppLocker service status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawAppLockerStatus.ps1">Download Script: Test-PawAppLockerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawAppLockerStatus.ps1
# Description: Checks the current configuration and operational status of the Application Identity service.

Write-Host "--- Auditing AppLocker Service Status ---" -ForegroundColor Cyan

# 1. Audit service state
$AppIDSvc = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue

if ($AppIDSvc) {
    if ($AppIDSvc.Status -eq "Running" -and $AppIDSvc.StartType -eq "Automatic") {
        Write-Host "    - AppLocker Service Status: Running | Startup: Automatic (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: AppLocker Service Status: $($AppIDSvc.Status) | Startup: $($AppIDSvc.StartType) (Should be Running/Automatic)" -ForegroundColor Red
    }
} else {
    Write-Host "    - VULNERABLE: Application Identity Service (AppIDSvc) is not installed." -ForegroundColor Red
}

# 2. Audit enforcement registry settings
$SrpPath = "HKLM:\Software\Policies\Microsoft\Windows\SrpV2"
$Collections = @("Exe", "Msi", "Script", "Appx")

if (Test-Path $SrpPath) {
    foreach ($Col in $Collections) {
        $ColPath = "$SrpPath\$Col"
        if (Test-Path $ColPath) {
            $Val = Get-ItemProperty -Path $ColPath -Name "EnforcementMode" -ErrorAction SilentlyContinue
            if ($null -ne $Val) {
                $Mode = if ($Val.EnforcementMode -eq 1) { "Enforced" } else { "Audit Only" }
                $Color = if ($Val.EnforcementMode -eq 1) { "Green" } else { "Yellow" }
                Write-Host "    - Collection $Col Enforcement: $Mode (Value: $($Val.EnforcementMode))" -ForegroundColor $Color
            } else {
                Write-Host "    - Collection $Col Enforcement: NOT CONFIGURED" -ForegroundColor Red
            }
        } else {
            Write-Host "    - Collection $Col Path: NOT FOUND" -ForegroundColor Red
        }
    }
} else {
    Write-Host "[-] AppLocker registry base path (SrpV2) not found. Policy is not deployed." -ForegroundColor Red
}

# 3. Audit NTVDM Disable Status
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (Test-Path $NtvdmPath) {
    $AppCompatVal = Get-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -ErrorAction SilentlyContinue
    if ($null -ne $AppCompatVal -and $AppCompatVal.Prevent16BitApp -eq 1) {
        Write-Host "    - NTVDM (16-bit AppCompat): Disabled (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - NTVDM (16-bit AppCompat): Enabled or Not Configured (Expected: Disabled)" -ForegroundColor Yellow
    }
} else {
    Write-Host "    - NTVDM (16-bit AppCompat): Not Configured (Expected: Disabled)" -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAppLockerService.ps1
# Description: Configures the Application Identity service (AppIDSvc) to start automatically and imports a robust AppLocker XML policy.

Write-Host "Applying AppLocker Identity service hardening..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$AppLockerService = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($AppLockerService) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    Start-Service -Name AppIDSvc -ErrorAction SilentlyContinue
    Write-Host "[+] Application Identity Service (AppIDSvc) set to Automatic and started." -ForegroundColor Green
} else {
    Write-Warning "[-] Application Identity Service not found on this machine."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerPawPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-002] Enable LSA Protection for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-lsa-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (LSASS) process manages security policies, user authentication, and credential tokens on Windows systems. Attackers targeting administrative workstations commonly attempt to extract plain-text credentials or NT hashes from LSASS memory using debugging tools (e.g., Mimikatz, Procdump).</xhtml:p>
        <xhtml:p>Enabling LSA Protection ensures that: 1. <xhtml:strong>Protected Process Light (PPL)</xhtml:strong>: The LSASS process runs as a Protected Process Light (PPL). 2. <xhtml:strong>Access Restriction</xhtml:strong>: Only verified, digitally signed code can load into LSASS, and standard processes (even those running as local system/administrator) cannot read the memory space of LSASS or inject code into it. 3. <xhtml:strong>Mitigating Dump Attacks</xhtml:strong>: Credential harvesting tools cannot dump LSASS memory to disk or scrape keys from LSA memory blocks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO linked to the PAWs Organizational Unit (OU) (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Local Security Authority</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure LSASS to run as a protected process</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure LSA to run as a protected process</xhtml:em>*: <xhtml:code>Enabled with UEFI Lock</xhtml:code> (or <xhtml:code>Enabled without UEFI Lock</xhtml:code> depending on management needs)</xhtml:li>
          <xhtml:li>Link the GPO to the PAWs Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry key on the PAW to run LSASS as a protected process.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawLsaProtection.ps1">Download Script: Configure-PawLsaProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawLsaProtection.ps1
# Description: Configures the RunAsPPL registry key to enable LSA Protection on PAWs.

Write-Host "Applying LSA Protection registry hardening..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "[+] LSA Protection (RunAsPPL) enabled in registry. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the local LSA Protection state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawLsaProtection.ps1">Download Script: Test-PawLsaProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawLsaProtection.ps1
# Description: Checks the registry settings and running process state to verify LSA Protection is active.

Write-Host "--- Auditing LSA Protection Status ---" -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$RunAsPPL = (Get-ItemProperty -Path $LsaPath -Name "RunAsPPL" -ErrorAction SilentlyContinue).RunAsPPL

if ($RunAsPPL -eq 1) {
    Write-Host "    - LSA Protection (RunAsPPL): Enabled (Secure)" -ForegroundColor Green
} else {
    Write-Host "    - VULNERABLE: LSA Protection (RunAsPPL) is not configured or disabled (Value: $($RunAsPPL))" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawLsaProtection.ps1
# Description: Configures the RunAsPPL registry key to enable LSA Protection on PAWs.

Write-Host "Applying LSA Protection registry hardening..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "[+] LSA Protection (RunAsPPL) enabled in registry. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-003] Restrict Local Administrators Group for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/restrict-local-administrators.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) represent Tier 0 administrative assets. Any user or group that has local administrative rights on a PAW can bypass operating system security boundaries, disable system protections, capture keystrokes, or extract cached credentials.</xhtml:p>
        <xhtml:p>Restricting local Administrators group membership ensures that: 1. <xhtml:strong>Administrative Rights Restriction</xhtml:strong>: Standard domain users and lower-tiered administrators (e.g., workstation support admins) are strictly prevented from executing code in an elevated context on the PAW. 2. <xhtml:strong>Tier Separation</xhtml:strong>: Administrative credentials from lower security tiers cannot compromise the PAW. Only dedicated Tier 0 administrators are allowed local administrative access. 3. <xhtml:strong>Authorized Control</xhtml:strong>: Membership is strictly controlled and reset periodically via Group Policy (Restricted Groups), preventing persistent privilege creep.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Deploy Restricted Groups via GPO to enforce local administrators group memberships: 1. Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>). 2. Edit the GPO linked to the PAWs Organizational Unit (OU) (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>). 3. Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Restricted Groups</xhtml:code> 4. Right-click <xhtml:strong>Restricted Groups</xhtml:strong> and select <xhtml:strong>Add Group</xhtml:strong>. 5. Type <xhtml:code>Administrators</xhtml:code> (or click Browse to find the local group). 6. Under <xhtml:strong>Members of this group</xhtml:strong>, define the allowed members: <xhtml:em> `Administrator` (the built-in local administrator account) </xhtml:em>
          <xhtml:code>DomainName\Tier0-Admins</xhtml:code> (dedicated Tier 0 administrative group) <xhtml:em> </xhtml:em>Do NOT include any standard domain users or lower-tier administrative groups.* 7. Link the GPO to the PAWs Organizational Unit (OU).</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and remediate unauthorized administrative accounts in the local Administrators group.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Clean-PawLocalAdministrators.ps1">Download Script: Clean-PawLocalAdministrators.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Clean-PawLocalAdministrators.ps1
# Description: Removes unauthorized accounts from the local Administrators group on PAWs.

Write-Host "--- Restricting Local Administrators Group on PAW ---" -ForegroundColor Cyan

# Define the list of authorized members
# Built-in Administrator and Tier 0 admin groups
$AuthorizedMembers = @("Administrator", "Tier0-Admins")

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    foreach ($Member in $LocalAdmins) {
        $Match = $false
        foreach ($Auth in $AuthorizedMembers) {
            if ($Member.Name -eq $Auth -or $Member.Name -like "*\$Auth" -or $Member.Name -eq "$env:COMPUTERNAME\$Auth") {
                $Match = $true
                break
            }
        }
        
        if (-not $Match) {
            Write-Host "[-] Removing unauthorized member from Administrators: $($Member.Name) (Source: $($Member.PrincipalSource))" -ForegroundColor Yellow
            try {
                Remove-LocalGroupMember -Group "Administrators" -Member $Member.Name -ErrorAction Stop
                Write-Host "    Successfully removed: $($Member.Name)" -ForegroundColor Green
            } catch {
                Write-Error "    Failed to remove: $($Member.Name). Error: $($_.Exception.Message)"
            }
        } else {
            Write-Host "[+] Member authorized: $($Member.Name)" -ForegroundColor Green
        }
    }
} else {
    Write-Error "Could not retrieve members of local Administrators group."
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local Administrators group memberships on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawLocalAdministrators.ps1">Download Script: Test-PawLocalAdministrators.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawLocalAdministrators.ps1
# Description: Audits local Administrators group memberships to ensure only authorized Tier 0 accounts are present.

Write-Host "--- Auditing PAW Local Administrators Group ---" -ForegroundColor Cyan

# Define the authorized domain/local patterns
$AuthorizedMembers = @("Administrator", "Tier0-Admins")

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    Write-Host "[*] Current members of local Administrators group:" -ForegroundColor Yellow
    foreach ($Member in $LocalAdmins) {
        $Match = $false
        foreach ($Auth in $AuthorizedMembers) {
            if ($Member.Name -eq $Auth -or $Member.Name -like "*\$Auth" -or $Member.Name -eq "$env:COMPUTERNAME\$Auth") {
                $Match = $true
                break
            }
        }
        
        if (-not $Match) {
            Write-Host "    - VULNERABLE: Unauthorized account '$($Member.Name)' (Source: $($Member.PrincipalSource)) has administrative access." -ForegroundColor Red
        } else {
            Write-Host "    - Member: $($Member.Name) | Source: $($Member.PrincipalSource) | Class: $($Member.ObjectClass) (Authorized)" -ForegroundColor Green
        }
    }
} else {
    Write-Error "Failed to retrieve local Administrators group members."
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Clean-PawLocalAdministrators.ps1
# Description: Removes unauthorized accounts from the local Administrators group on PAWs.

Write-Host "--- Restricting Local Administrators Group on PAW ---" -ForegroundColor Cyan

# Define the list of authorized members
# Built-in Administrator and Tier 0 admin groups
$AuthorizedMembers = @("Administrator", "Tier0-Admins")

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    foreach ($Member in $LocalAdmins) {
        $Match = $false
        foreach ($Auth in $AuthorizedMembers) {
            if ($Member.Name -eq $Auth -or $Member.Name -like "*\$Auth" -or $Member.Name -eq "$env:COMPUTERNAME\$Auth") {
                $Match = $true
                break
            }
        }
        
        if (-not $Match) {
            Write-Host "[-] Removing unauthorized member from Administrators: $($Member.Name) (Source: $($Member.PrincipalSource))" -ForegroundColor Yellow
            try {
                Remove-LocalGroupMember -Group "Administrators" -Member $Member.Name -ErrorAction Stop
                Write-Host "    Successfully removed: $($Member.Name)" -ForegroundColor Green
            } catch {
                Write-Error "    Failed to remove: $($Member.Name). Error: $($_.Exception.Message)"
            }
        } else {
            Write-Host "[+] Member authorized: $($Member.Name)" -ForegroundColor Green
        }
    }
} else {
    Write-Error "Could not retrieve members of local Administrators group."
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-004" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-004] Enforce BitLocker with TPM and Startup PIN for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 0 Privileged Access Workstations (PAWs).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-bitlocker.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the secure root of trust for administering Tier 0 Active Directory resources. Because these devices are physical endpoints, they are susceptible to theft, loss, and unauthorized physical access.</xhtml:p>
        <xhtml:p>To achieve maximum protection, the PAW BitLocker configuration enforces a significantly more stringent baseline than standard client endpoints: 1. <xhtml:strong>TPM and Startup PIN</xhtml:strong>: Enforcing a pre-boot Startup PIN combined with TPM validation ensures that the drive cannot be unlocked or booted without explicit administrator presence. Network Unlock is prohibited on PAWs to prevent automatic decryption when connected to a local switch, ensuring physical presence verification is mandatory for every boot. 2. <xhtml:strong>Disabling Sleep/Standby States (S1-S3)</xhtml:strong>: When a system enters a standby/sleep state, the BitLocker volume decryption keys remain stored in the volatile memory (RAM). An attacker with brief physical access to a sleeping PAW can exploit Direct Memory Access (DMA) interfaces (such as Thunderbolt, FireWire, or PCIe slots) or perform a cold-boot attack to extract the decryption keys directly from the RAM. Disabling S1-S3 standby states forces the system to either shut down (S5) or hibernate (S4), writing the RAM contents back to the encrypted disk and purging the keys from volatile memory. 3. <xhtml:strong>Kernel DMA Protection</xhtml:strong>: This blocks peripheral devices (Thunderbolt, PCIe) from initiating DMA requests unless the OS is fully booted, authorized, and running driver-level Input-Output Memory Management Unit (IOMMU) protection, preventing DMA memory extraction during the pre-boot and OS load phases. 4. <xhtml:strong>Enhanced Startup PINs</xhtml:strong>: This allows administrators to use alphanumeric characters, symbols, uppercase and lowercase letters, and spaces in their pre-boot Startup PIN rather than just numbers, increasing entropy and resistance to PIN-guessing attacks. 5. <xhtml:strong>Active Directory Backup &amp; Recovery Password Rotation</xhtml:strong>: Ensures all BitLocker recovery keys are automatically backed up to Active Directory before encryption begins. In addition, when a recovery key is used to unlock a PAW, it must be automatically rotated and updated in Active Directory to prevent the reuse of compromised recovery keys.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Enforce BitLocker Encryption Strength</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Choose drive encryption method and cipher strength (Windows 10 [Version 1511] and later)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select the encryption method</xhtml:em>*: <xhtml:code>XTS-AES 256-bit</xhtml:code> (for Operating System drives)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Enforce TPM + Startup PIN and Enhanced PIN Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption\Operating System Drives</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Require additional authentication at startup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure Options</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Set <xhtml:code>Configure TPM startup</xhtml:code>: <xhtml:code>Require TPM</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Set <xhtml:code>Configure TPM startup PIN</xhtml:code>: <xhtml:code>Require startup PIN with TPM</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Set <xhtml:code>Configure TPM startup key</xhtml:code>: <xhtml:code>Do not allow startup key with TPM</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Set <xhtml:code>Configure TPM startup key and PIN</xhtml:code>: <xhtml:code>Do not allow startup key and PIN with TPM</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Check <xhtml:code>Allow BitLocker without a compatible TPM</xhtml:code>: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure use of enhanced PINs for startup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Minimum PIN length for startup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minimum characters</xhtml:em>*: <xhtml:code>8</xhtml:code> (or higher depending on local organizational policy)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Configure Active Directory Backup and Key Rotation</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the same OS Drives folder, configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Choose how BitLocker-protected operating system drives can be recovered</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure Options</xhtml:em>*:</xhtml:li>
          <xhtml:li>* Check <xhtml:code>Allow data recovery agent</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Check <xhtml:code>Save BitLocker recovery information to Active Directory Domain Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Set <xhtml:code>Configure user storage of BitLocker recovery information</xhtml:code>: <xhtml:code>Store recovery passwords and key packages</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Check <xhtml:code>Do not enable BitLocker until recovery information is stored in AD DS for operating system drives</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure recovery password rotation for AD DS-joined computers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rotation options</xhtml:em>*: <xhtml:code>Must rotate the recovery password for OS drives and fixed data drives</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 4: Disable Sleep/Standby States (S1-S3)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Power Management\Sleep Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Allow standby states (S1-S3) when sleeping (plugged in)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Allow standby states (S1-S3) when sleeping (on battery)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 5: Enable Kernel DMA Protection</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Enable Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on the PAW to apply registry configuration baselines and enable BitLocker.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PAWBitLockerEncryption.ps1">Download Script: Set-PAWBitLockerEncryption.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PAWBitLockerEncryption.ps1
# Configures registry settings for PAW BitLocker, disables sleep states, and enables encryption.

Write-Host "--- Enforcing Stringent PAW BitLocker Baseline ---" -ForegroundColor Cyan

# 1. Enforce encryption strength (XTS-AES 256 = 7)
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "EncryptionMethodWithXtsOs" -Value 7 -Type DWord

# 2. Configure TPM + Startup PIN, AD Backup, and Enhanced PINs in registry
Set-ItemProperty -Path $FvePath -Name "UseAdvancedStartup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "EnableNonTpm" -Value 0 -Type DWord
Set-ItemProperty -Path $FvePath -Name "UseTPM" -Value 2 -Type DWord # 2 = Require
Set-ItemProperty -Path $FvePath -Name "UseTPMPIN" -Value 2 -Type DWord # 2 = Require
Set-ItemProperty -Path $FvePath -Name "UseEnhancedPINs" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "MinPINLength" -Value 8 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecovery" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecoveryPassword" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSBackupSaveSource" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSActiveDirectoryBackup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRequireActiveDirectoryBackup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecoveryPasswordRotation" -Value 1 -Type DWord # 1 = Enforce rotation

# 3. Disable Sleep States S1-S3 via GPO Registry override
$PowerSleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc251b-215d-4f10-ae40-e226dbe3c6a3"
if (-not (Test-Path $PowerSleepPath)) {
    New-Item -Path $PowerSleepPath -Force | Out-Null
}
Set-ItemProperty -Path $PowerSleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $PowerSleepPath -Name "DCSettingIndex" -Value 0 -Type DWord

# Enforce hibernate locally using powercfg
powercfg /hibernate on
Write-Host "[+] Sleep states S1-S3 disabled, and Hibernation enabled." -ForegroundColor Green

# 4. Enable Kernel DMA Protection in registry
$DmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $DmaPath)) {
    New-Item -Path $DmaPath -Force | Out-Null
}
Set-ItemProperty -Path $DmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection registry configuration applied." -ForegroundColor Green

# 5. Enable BitLocker on C: drive using TPM and Startup PIN
$Volume = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue
if ($Volume.ProtectionStatus -eq "Off") {
    Write-Host "[+] Activating BitLocker on C: volume..." -ForegroundColor Gray
    
    # We must first define a temporary PIN to enable startup PIN protection programmatically
    # The administrator must change this PIN immediately on next reboot
    $TempPin = "P@ssw0rdPIN1"
    $SecurePin = New-Object System.Security.SecureString
    foreach ($Char in $TempPin.ToCharArray()) {
        $SecurePin.AppendChar($Char)
    }
    
    Enable-BitLocker -MountPoint "C:" `
        -EncryptionMethod XtsAes256 `
        -UsedSpaceOnly `
        -Pin $SecurePin `
        -TpmAndPinProtector `
        -AdBackupRequired
        
    Write-Host "[+] BitLocker initiated with TPM and Startup PIN. Recovery keys sent to AD." -ForegroundColor Green
} else {
    Write-Host "[+] BitLocker is already enabled on C: (Protection Status: $($Volume.ProtectionStatus))." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the PAW BitLocker status and security parameters:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-PAWBitLockerStatus.ps1">Download Script: Test-PAWBitLockerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PAWBitLockerStatus.ps1
# Audits current BitLocker configuration, active protectors, sleep state, and DMA protection.

Write-Host "--- Auditing PAW BitLocker Security Parameters ---" -ForegroundColor Cyan

# 1. Query BitLocker protection and key protector types
$Volume = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue
if ($Volume) {
    $StatusColor = if ($Volume.ProtectionStatus -eq "On") { "Green" } else { "Red" }
    Write-Host "    - Protection Status: $($Volume.ProtectionStatus)" -ForegroundColor $StatusColor
    Write-Host "    - Encryption Method: $($Volume.EncryptionMethod)" -ForegroundColor White
    
    $HasTpmPin = $false
    foreach ($Protector in $Volume.KeyProtector) {
        if ($Protector.KeyProtectorType -eq "TpmAndPin") {
            $HasTpmPin = $true
        }
        Write-Host "    - Active Protector: $($Protector.KeyProtectorType)" -ForegroundColor White
    }
    
    if ($HasTpmPin) {
        Write-Host "    [+] TPM and Startup PIN is ACTIVE." -ForegroundColor Green
    } else {
        Write-Host "    [-] TPM and Startup PIN is MISSING." -ForegroundColor Red
    }
} else {
    Write-Error "BitLocker volume information could not be retrieved."
}

# 2. Check Sleep State S1-S3 status
$SleepVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc251b-215d-4f10-ae40-e226dbe3c6a3" -Name "ACSettingIndex" -ErrorAction SilentlyContinue
if ($SleepVal -and $SleepVal.ACSettingIndex -eq 0) {
    Write-Host "    [+] Standby Sleep States (S1-S3) are disabled." -ForegroundColor Green
} else {
    Write-Host "    [-] Standby Sleep States (S1-S3) are enabled (Risk of DMA attack)." -ForegroundColor Red
}

# 3. Check Kernel DMA Protection
$DmaVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection" -Name "DeviceEnumerationPolicy" -ErrorAction SilentlyContinue
if ($DmaVal -and $DmaVal.DeviceEnumerationPolicy -eq 0) {
    Write-Host "    [+] Kernel DMA Protection is enabled." -ForegroundColor Green
} else {
    Write-Host "    [-] Kernel DMA Protection is disabled." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PAWBitLockerEncryption.ps1
# Configures registry settings for PAW BitLocker, disables sleep states, and enables encryption.

Write-Host "--- Enforcing Stringent PAW BitLocker Baseline ---" -ForegroundColor Cyan

# 1. Enforce encryption strength (XTS-AES 256 = 7)
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "EncryptionMethodWithXtsOs" -Value 7 -Type DWord

# 2. Configure TPM + Startup PIN, AD Backup, and Enhanced PINs in registry
Set-ItemProperty -Path $FvePath -Name "UseAdvancedStartup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "EnableNonTpm" -Value 0 -Type DWord
Set-ItemProperty -Path $FvePath -Name "UseTPM" -Value 2 -Type DWord # 2 = Require
Set-ItemProperty -Path $FvePath -Name "UseTPMPIN" -Value 2 -Type DWord # 2 = Require
Set-ItemProperty -Path $FvePath -Name "UseEnhancedPINs" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "MinPINLength" -Value 8 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecovery" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecoveryPassword" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSBackupSaveSource" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSActiveDirectoryBackup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRequireActiveDirectoryBackup" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "OSRecoveryPasswordRotation" -Value 1 -Type DWord # 1 = Enforce rotation

# 3. Disable Sleep States S1-S3 via GPO Registry override
$PowerSleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc251b-215d-4f10-ae40-e226dbe3c6a3"
if (-not (Test-Path $PowerSleepPath)) {
    New-Item -Path $PowerSleepPath -Force | Out-Null
}
Set-ItemProperty -Path $PowerSleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $PowerSleepPath -Name "DCSettingIndex" -Value 0 -Type DWord

# Enforce hibernate locally using powercfg
powercfg /hibernate on
Write-Host "[+] Sleep states S1-S3 disabled, and Hibernation enabled." -ForegroundColor Green

# 4. Enable Kernel DMA Protection in registry
$DmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $DmaPath)) {
    New-Item -Path $DmaPath -Force | Out-Null
}
Set-ItemProperty -Path $DmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection registry configuration applied." -ForegroundColor Green

# 5. Enable BitLocker on C: drive using TPM and Startup PIN
$Volume = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue
if ($Volume.ProtectionStatus -eq "Off") {
    Write-Host "[+] Activating BitLocker on C: volume..." -ForegroundColor Gray
    
    # We must first define a temporary PIN to enable startup PIN protection programmatically
    # The administrator must change this PIN immediately on next reboot
    $TempPin = "P@ssw0rdPIN1"
    $SecurePin = New-Object System.Security.SecureString
    foreach ($Char in $TempPin.ToCharArray()) {
        $SecurePin.AppendChar($Char)
    }
    
    Enable-BitLocker -MountPoint "C:" `
        -EncryptionMethod XtsAes256 `
        -UsedSpaceOnly `
        -Pin $SecurePin `
        -TpmAndPinProtector `
        -AdBackupRequired
        
    Write-Host "[+] BitLocker initiated with TPM and Startup PIN. Recovery keys sent to AD." -ForegroundColor Green
} else {
    Write-Host "[+] BitLocker is already enabled on C: (Protection Status: $($Volume.ProtectionStatus))." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-005] UEFI Firmware Security Hardening</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Domain Controllers, refer to [REQ-DC-157](../02-domain-controllers/configure-uefi-security.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-013](../08-endpoints/configure-uefi-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-uefi-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated administrative bastions that operate at the pinnacle of the enterprise security architecture (Tier 0). Compromise of a PAW grants adversaries the credentials necessary to commandeer identity infrastructure, cloud tenants, and enterprise directory data.</xhtml:p>
        <xhtml:p>If an attacker obtains physical access to a PAW, or if malicious code gains low-level administrative control, vulnerabilities in the boot chain or legacy firmware interfaces can be exploited to bypass operating system security boundaries, defeat BitLocker disk encryption, or implant persistent firmware bootkits before the Windows kernel loads.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual UEFI Firmware Configuration (Preferred)</xhtml:h3>
        <xhtml:p>UEFI settings must be configured directly within the hardware platform firmware interface during system startup.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Turn on or restart the workstation and access the UEFI setup utility by pressing the vendor-specific key during POST (typically Delete, F2, F10, or F12).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Authentication</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select the option to set the </xhtml:em>
            <xhtml:em>Administrator Password</xhtml:em>
            <xhtml:em> (also referred to as the </xhtml:em>
            <xhtml:em>Supervisor Password</xhtml:em>*). Do not configure a User Password, as that prompts for authentication on every boot rather than only when entering configuration settings.</xhtml:li>
          <xhtml:li>* Enter a strong, complex password. Record this password in the enterprise Tier 0 credential vault.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Boot</xhtml:strong> or <xhtml:strong>System Configuration</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate the </xhtml:em>
            <xhtml:em>Boot Mode</xhtml:em>
            <xhtml:em> setting and set it to </xhtml:em>
            <xhtml:em>UEFI Only</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Native UEFI</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>CSM (Compatibility Support Module)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Legacy Boot Support</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Fast Boot</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Quick Boot</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>* (forcing complete POST diagnostics and full TPM initialization on every boot).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Boot Order</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Boot Priority</xhtml:em>*):</xhtml:li>
          <xhtml:li>* Set the primary boot option to the internal system storage drive (typically containing the Windows Boot Manager partition).</xhtml:li>
          <xhtml:li>* Disable all other boot options (such as USB, SD Card, Optical Drive, and Network PXE Boot) or set them to disabled in the boot menu.</xhtml:li>
          <xhtml:li>* Enable the option to prompt for the UEFI administrator password if a user attempts to access the boot override menu (typically F12 or F8).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Advanced</xhtml:strong>, <xhtml:strong>CPU Configuration</xhtml:strong>, or <xhtml:strong>Security Chip</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Intel Virtualization Technology (VT-x)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD-V</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Intel VT for Directed I/O (VT-d)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD IOMMU</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (required for IOMMU/Kernel DMA Protection).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>TPM 2.0 Device</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Security Chip / Intel PTT / AMD fTPM</xhtml:em>
            <xhtml:em>) and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Active</xhtml:em>* (with SHA-256 PCR bank).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Memory Overwrite Request Control Lock</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>MOR Lock</xhtml:em>
            <xhtml:em>) and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Secure Boot</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure </xhtml:em>
            <xhtml:em>Secure Boot</xhtml:em>
            <xhtml:em> is </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> and the </xhtml:em>
            <xhtml:em>Secure Boot Mode</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Deployed</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>User Mode</xhtml:em>*.</xhtml:li>
          <xhtml:li>* Harden the certificates allowlist:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Exchange Key (KEK)</xhtml:em>*: Must only contain "Microsoft Corporation KEK CA 2011" and "Microsoft Corporation KEK 2K CA 2023".</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Signature Database (db)</xhtml:em>*: Must only contain "Microsoft Windows Production PCA 2011" and "Windows UEFI CA 2023". Remove "Microsoft UEFI CA 2011" and "Microsoft Option ROM UEFI CA 2023" unless strictly required by specific physical PCIe expansion hardware.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Advanced</xhtml:strong> or <xhtml:strong>Firmware Update</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate the option for </xhtml:em>
            <xhtml:em>BIOS Flash Protection</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Firmware Rollback Protection</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Block Downgrades</xhtml:em>*.</xhtml:li>
          <xhtml:li>Save the configuration and restart the workstation.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Remediation &amp; OS Boot Hardening</xhtml:h3>
        <xhtml:p>Run the following script to configure OS-level boot parameters (disabling Windows Fast Startup, ensuring memory protections), audit OEM firmware capabilities, and guide hardware-level configuration.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PawUEFISecurity.ps1">Download Script: Set-PawUEFISecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PawUEFISecurity.ps1
# Description: Configures OS-level boot parameters and audits OEM firmware configuration for PAWs.

Write-Host "--- Configuring PAW UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags (Requires UEFI and Secure Boot)
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 2 = DMA Protection, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 3 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features set to Secure Boot and DMA Protection (Value = 3)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Hardware OEM and report vendor tooling commands
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue
Write-Host "`nOEM Firmware Detection:" -ForegroundColor Cyan
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($Bios.Manufacturer -match "Dell") {
    Write-Host "  [i] Dell Platform detected. To enforce UEFI settings via Dell Command | PowerShell Provider:" -ForegroundColor Yellow
    Write-Host "      Import-Module DellBIOSProvider" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Security\AdminPassword 'YourStrongPassword'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Boot\BootMode 'UEFI'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\SecureBoot\SecureBoot 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\Virtualization 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\VtForDirectIO 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\PostBehavior\Fastboot 'Thorough'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "HP") {
    Write-Host "  [i] HP Platform detected. To enforce UEFI settings via HP Client Management Script Library (HPCMSL):" -ForegroundColor Yellow
    Write-Host "      Import-Module HPCMSL" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Boot Mode' -Value 'UEFI Native (without CSM)'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Secure Boot' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Fast Boot' -Value 'Disable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology for Directed I/O' -Value 'Enable'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "Lenovo") {
    Write-Host "  [i] Lenovo Platform detected. To enforce UEFI settings via Lenovo BIOS WMI interface:" -ForegroundColor Yellow
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('BootMode,UEFI')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('SecureBoot,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('IntelVirtualizationTechnology,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('VTd,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SaveBiosSettings -namespace root\wmi).SaveBiosSettings()" -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PawUEFISecurity.ps1
# Description: Configures OS-level boot parameters and audits OEM firmware configuration for PAWs.

Write-Host "--- Configuring PAW UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags (Requires UEFI and Secure Boot)
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 2 = DMA Protection, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 3 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features set to Secure Boot and DMA Protection (Value = 3)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Hardware OEM and report vendor tooling commands
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue
Write-Host "`nOEM Firmware Detection:" -ForegroundColor Cyan
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($Bios.Manufacturer -match "Dell") {
    Write-Host "  [i] Dell Platform detected. To enforce UEFI settings via Dell Command | PowerShell Provider:" -ForegroundColor Yellow
    Write-Host "      Import-Module DellBIOSProvider" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Security\AdminPassword 'YourStrongPassword'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Boot\BootMode 'UEFI'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\SecureBoot\SecureBoot 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\Virtualization 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\VtForDirectIO 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\PostBehavior\Fastboot 'Thorough'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "HP") {
    Write-Host "  [i] HP Platform detected. To enforce UEFI settings via HP Client Management Script Library (HPCMSL):" -ForegroundColor Yellow
    Write-Host "      Import-Module HPCMSL" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Boot Mode' -Value 'UEFI Native (without CSM)'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Secure Boot' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Fast Boot' -Value 'Disable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology for Directed I/O' -Value 'Enable'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "Lenovo") {
    Write-Host "  [i] Lenovo Platform detected. To enforce UEFI settings via Lenovo BIOS WMI interface:" -ForegroundColor Yellow
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('BootMode,UEFI')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('SecureBoot,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('IntelVirtualizationTechnology,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('VTd,Enable')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SaveBiosSettings -namespace root\wmi).SaveBiosSettings()" -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-006] Enable Hardware Virtualization and DMA Protection</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-hardware-virtualization-and-dma-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Virtualization-Based Security (VBS) and Windows Defender Credential Guard isolate sensitive security processes (like LSA) inside a hardware-virtualized container to prevent memory dumping and credential harvesting. However, these OS-level security boundaries are entirely reliant on hardware-level protections.</xhtml:p>
        <xhtml:p>Enabling hardware virtualization and DMA protection guarantees: 1. <xhtml:strong>Isolated Execution Environment</xhtml:strong>: Enforcing CPU Virtualization Extensions (Intel VT-x or AMD-V) in the UEFI allows the hypervisor to isolate the VBS secure kernel from the host Windows operating system. 2. <xhtml:strong>Physical DMA Protection</xhtml:strong>: Enforcing IOMMU (Intel VT-d or AMD-Vi) at the firmware level enables Kernel DMA Protection. This blocks malicious peripherals (e.g., PCIe cards or Thunderbolt devices) from executing unauthorized Direct Memory Access (DMA) attacks to read or write to host system memory, preventing attackers from extracting BitLocker keys or credential secrets directly from RAM. 3. <xhtml:strong>Hardware Root of Trust</xhtml:strong>: Activating the Trusted Platform Module (TPM) 2.0 enables cryptographic boot measurement logging (PCR banks). TPM 2.0 ensures that the system boot configuration has not been modified prior to unsealing the BitLocker volume decryption keys.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce Kernel DMA Protection across the PAW infrastructure, implement the following GPO settings:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Enable Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate OU containing target PAWs.</xhtml:li>
        </xhtml:ol>
        <xhtml:p>
          <xhtml:em>Note: Enforce hardware-level CPU Virtualization (VT-x/AMD-V), IOMMU (VT-d/AMD-Vi), and TPM 2.0 manually in the UEFI menu of each device.</xhtml:em>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure local registry keys to enforce Kernel DMA Protection and programmatically audit the hardware security baseline.</xhtml:p>
        <xhtml:h4>1. Local Remediation (Enforce Kernel DMA Protection)</xhtml:h4>
        <xhtml:p>Run the following script to enforce the DMA Protection policy locally:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-KernelDMAProtection.ps1">Download Script: Configure-KernelDMAProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-KernelDMAProtection.ps1
# Description: Configures registry keys to enable Kernel DMA Protection.

Write-Host "--- Enforcing Kernel DMA Protection ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# DeviceEnumerationPolicy = 0 (Block all DMA until user logs on)
Set-ItemProperty -Path $RegPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "Status: Kernel DMA Protection registry configuration applied." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Audit (TPM, Virtualization, and DMA Support)</xhtml:h4>
        <xhtml:p>Run the following script to audit the status of the required hardware security components:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-HardwareSecurityFeatures.ps1">Download Script: Audit-HardwareSecurityFeatures.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-HardwareSecurityFeatures.ps1
# Description: Audits TPM 2.0, CPU Virtualization, and IOMMU/DMA status.

Write-Host "--- Auditing Hardware Security Features ---" -ForegroundColor Cyan

# 1. Audit TPM 2.0 Status
$Tpm = Get-Tpm -ErrorAction SilentlyContinue
if ($Tpm) {
    if ($Tpm.TpmPresent -eq $true) {
        $TpmColor = "Red"
        if ($Tpm.TpmReady -eq $true) {
            $TpmColor = "Green"
        }
        Write-Host "Status: TPM Present: $($Tpm.TpmPresent) | Ready: $($Tpm.TpmReady)" -ForegroundColor $TpmColor
    } else {
        Write-Host "VULNERABLE: TPM 2.0 is not detected on this system." -ForegroundColor Red
    }
} else {
    Write-Host "VULNERABLE: TPM verification cmdlet failed." -ForegroundColor Red
}

# 2. Audit VBS and DMA Status via Win32_DeviceGuard
try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    
    # VirtualizationBasedSecurityStatus: 2 = Running
    $VbsStatus = $DG.VirtualizationBasedSecurityStatus
    $VbsColor = "Red"
    if ($VbsStatus -eq 2) {
        $VbsColor = "Green"
    }
    Write-Host "Status: Virtualization-Based Security Status: $($VbsStatus) (Required = 2 [Running])" -ForegroundColor $VbsColor
    
    # AvailableSecurityProperties: 3 = DMA Protection (IOMMU)
    $DmaSupported = $DG.AvailableSecurityProperties -contains 3
    $DmaColor = "Red"
    if ($DmaSupported -eq $true) {
        $DmaColor = "Green"
    }
    Write-Host "Status: Hardware IOMMU/DMA Protection: $($DmaSupported)" -ForegroundColor $DmaColor
    
    # RequiredSecurityProperties: 3 = DMA Protection enforced
    $DmaEnforced = $DG.RequiredSecurityProperties -contains 3
    $EnforcedColor = "Red"
    if ($DmaEnforced -eq $true) {
        $EnforcedColor = "Green"
    }
    Write-Host "Status: DMA Protection Policy Enforced: $($DmaEnforced)" -ForegroundColor $EnforcedColor
    
} catch {
    Write-Host "VULNERABLE: Win32_DeviceGuard WMI class could not be queried. VBS is likely inactive." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-KernelDMAProtection.ps1
# Description: Configures registry keys to enable Kernel DMA Protection.

Write-Host "--- Enforcing Kernel DMA Protection ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# DeviceEnumerationPolicy = 0 (Block all DMA until user logs on)
Set-ItemProperty -Path $RegPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "Status: Kernel DMA Protection registry configuration applied." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-007" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-007] Disable Windows Platform Binary Table (WPBT)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/disable-wpbt.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Platform Binary Table (WPBT) is an ACPI firmware table that allows hardware manufacturers (OEMs) to execute proprietary binaries in kernel space during the Windows boot phase. Windows automatically extracts the binary from the table and runs it with system privileges before security software, third-party agents, or standard driver verifications are fully initialized.</xhtml:p>
        <xhtml:p>While designed to facilitate automated driver provisioning and anti-theft services, this mechanism represents a significant security risk: 1. <xhtml:strong>Firmware-to-OS Attack Vector</xhtml:strong>: Malicious actors utilizing UEFI rootkits, physical firmware flashing tools, or supply-chain firmware implants can compromise the WPBT table to execute arbitrary code at boot, bypassing Secure Boot and operating system-level integrity checks. 2. <xhtml:strong>Privilege Escalation Risks</xhtml:strong>: Historically, OEM software delivered via the WPBT has introduced high-severity local privilege escalation and remote code execution vulnerabilities due to inadequate code review or poor permission management. 3. <xhtml:strong>Control and Transparency</xhtml:strong>: Executing firmware-rooted binaries without administrative visibility or operating system validation bypasses normal software lifecycle and endpoint protection policies.</xhtml:p>
        <xhtml:p>Disabling WPBT execution prevents Windows from parsing the ACPI table and running the embedded software, mitigating boot-level integrity bypasses.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Because there is no default ADMX administrative template to manage WPBT execution, the setting must be configured as a Registry Preference under the PAW policy:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to your PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New -&gt; Registry Item</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>DisableWpbtExecution</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save the preference.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to configure the registry setting locally on the system:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableWpbt.ps1">Download Script: Configure-DisableWpbt.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableWpbt.ps1
# Description: Disables Windows Platform Binary Table (WPBT) execution in the registry.

Write-Host "Applying hardening requirement: Disable WPBT Execution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "Registry setting DisableWpbtExecution configured to 1." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that the registry value is correctly enforced:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-WpbtStatus.ps1">Download Script: Get-WpbtStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WpbtStatus.ps1
# Description: Audits the registry state for WPBT execution prevention.

Write-Host "--- Auditing WPBT Security Posture ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"

$RegistryValue = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue

if ($RegistryValue) {
    $Setting = $RegistryValue.DisableWpbtExecution
    if ($Setting -eq 1) {
        Write-Host "Status: WPBT execution is disabled (DisableWpbtExecution = 1)." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: WPBT execution is enabled. Value is $($Setting)." -ForegroundColor Red
    }
} else {
    Write-Host "VULNERABLE: DisableWpbtExecution registry value is not configured (defaulting to execution enabled)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWpbt.ps1
# Description: Disables Windows Platform Binary Table (WPBT) execution in the registry.

Write-Host "Applying hardening requirement: Disable WPBT Execution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "Registry setting DisableWpbtExecution configured to 1." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7007" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-010" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-010] Enable VBS and Credential Guard for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-vbs-credential-guard.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) contain Tier 0 administrative tokens. A compromise of a PAW leads to a direct compromise of the Active Directory database (NTDS.dit) and full domain domain control. Mitigating credential dumping is the single most critical security objective for a PAW.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Virtualization-Based Security (VBS)</xhtml:strong>: VBS establishes an isolated, secure kernel space using hypervisor hardware virtualization. This secure kernel is separated from the host operating system, preventing root-level exploits from accessing virtualized memory blocks.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Credential Guard</xhtml:strong>: Running within the VBS secure kernel, Credential Guard stores credential secrets (NTLM hashes, Kerberos TGTs) inside an isolated memory container. By shifting these secrets outside the standard Local Security Authority (LSA) process memory space, it blocks credential-dumping utilities (like Mimikatz) from harvesting secrets from memory.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Secure Launch</xhtml:strong>: System Guard Secure Launch protects firmware boot integrity by using hardware-enforced boot measurements. It isolates the hypervisor startup from potential rootkits or boot-level malware.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>UEFI Memory Attributes Table (MAT)</xhtml:strong>: Enforcing UEFI MAT ensures that the bootloader validates page permissions in firmware, preventing buffer overflow or execution redirection vulnerabilities in pre-boot configurations.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn On Virtualization Based Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Platform Security Level</xhtml:em>*: <xhtml:code>Secure Boot</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Virtualization Based Protection of Code Integrity</xhtml:em>*: <xhtml:code>Enabled with UEFI lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Credential Guard Configuration</xhtml:em>*: <xhtml:code>Enabled with UEFI lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Secure Launch Configuration</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Require UEFI Memory Attributes Table</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the PAWs Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry parameters to activate VBS, Credential Guard, and Secure Launch.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enable-PawVBSCredentialGuard.ps1">Download Script: Enable-PawVBSCredentialGuard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enable-PawVBSCredentialGuard.ps1
# Description: Configures local registry keys to activate VBS and Credential Guard on PAWs.

Write-Host "--- Enforcing VBS &amp; Credential Guard for PAWs ---" -ForegroundColor Cyan

$DeviceGuardPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard"

if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

# Enable Virtualization-Based Security (VBS)
Set-ItemProperty -Path $DeviceGuardPath -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
# RequirePlatformSecurityFeatures = 1 (Secure Boot)
Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord
# HypervisorEnforcedCodeIntegrity = 1 (HVCI / Memory Integrity Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "HypervisorEnforcedCodeIntegrity" -Value 1 -Type DWord
# LsaCfgFlags = 1 (Credential Guard Enabled with UEFI Lock)
Set-ItemProperty -Path $DeviceGuardPath -Name "LsaCfgFlags" -Value 1 -Type DWord
# ConfigureSystemGuardLaunch = 1 (Secure Launch Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "ConfigureSystemGuardLaunch" -Value 1 -Type DWord
# HVCIMATRequired = 1 (Require UEFI Memory Attributes Table)
Set-ItemProperty -Path $DeviceGuardPath -Name "HVCIMATRequired" -Value 1 -Type DWord

Write-Host "[+] PAW VBS and Credential Guard registry settings applied. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit VBS and Credential Guard status using WMI and Registry:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-PawVBSCredentialGuard.ps1">Download Script: Test-PawVBSCredentialGuard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawVBSCredentialGuard.ps1
# Description: Queries the local Win32_DeviceGuard class and registry settings to verify VBS protection states on PAWs.

Write-Host "--- Auditing PAW Virtualization-Based Security Baseline ---" -ForegroundColor Cyan

try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    
    # SecurityServicesRunning: 1 = Credential Guard, 2 = HVCI
    $CredGuardRunning = $DG.SecurityServicesRunning -contains 1
    $HvciRunning = $DG.SecurityServicesRunning -contains 2
    
    $VbsColor = if ($DG.VirtualizationBasedSecurityStatus -eq 2) { "Green" } else { "Red" }
    $CredColor = if ($CredGuardRunning) { "Green" } else { "Red" }
    $HvciColor = if ($HvciRunning) { "Green" } else { "Red" }
    
    Write-Host "    - VBS Status: $($DG.VirtualizationBasedSecurityStatus) (Required = 2 [Running])" -ForegroundColor $VbsColor
    Write-Host "    - Credential Guard Running: $CredGuardRunning (Required = True)" -ForegroundColor $CredColor
    Write-Host "    - Hypervisor Code Integrity Running: $HvciRunning (Required = True)" -ForegroundColor $HvciColor
    
    # Query registry properties for System Guard and UEFI MAT
    $SystemGuard = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" -Name "ConfigureSystemGuardLaunch" -ErrorAction SilentlyContinue).ConfigureSystemGuardLaunch
    $MatRequired = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" -Name "HVCIMATRequired" -ErrorAction SilentlyContinue).HVCIMATRequired
    
    $SgColor = if ($SystemGuard -eq 1) { "Green" } else { "Red" }
    $MatColor = if ($MatRequired -eq 1) { "Green" } else { "Red" }
    
    Write-Host "    - System Guard Secure Launch: $SystemGuard (Required = 1)" -ForegroundColor $SgColor
    Write-Host "    - UEFI Memory Attributes Table Required: $MatRequired (Required = 1)" -ForegroundColor $MatColor
} catch {
    Write-Host "    - VULNERABLE: DeviceGuard WMI class could not be queried. VBS is likely disabled." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enable-PawVBSCredentialGuard.ps1
# Description: Configures local registry keys to activate VBS and Credential Guard on PAWs.

Write-Host "--- Enforcing VBS &amp; Credential Guard for PAWs ---" -ForegroundColor Cyan

$DeviceGuardPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard"

if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

# Enable Virtualization-Based Security (VBS)
Set-ItemProperty -Path $DeviceGuardPath -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
# RequirePlatformSecurityFeatures = 1 (Secure Boot)
Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord
# HypervisorEnforcedCodeIntegrity = 1 (HVCI / Memory Integrity Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "HypervisorEnforcedCodeIntegrity" -Value 1 -Type DWord
# LsaCfgFlags = 1 (Credential Guard Enabled with UEFI Lock)
Set-ItemProperty -Path $DeviceGuardPath -Name "LsaCfgFlags" -Value 1 -Type DWord
# ConfigureSystemGuardLaunch = 1 (Secure Launch Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "ConfigureSystemGuardLaunch" -Value 1 -Type DWord
# HVCIMATRequired = 1 (Require UEFI Memory Attributes Table)
Set-ItemProperty -Path $DeviceGuardPath -Name "HVCIMATRequired" -Value 1 -Type DWord

Write-Host "[+] PAW VBS and Credential Guard registry settings applied. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-011" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-011] Harden DMA and Physical Security for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Domain Controllers, refer to [REQ-DC-158](../02-domain-controllers/harden-dma-and-physical-security.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-017](../08-endpoints/harden-dma-and-physical-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/harden-dma-and-physical-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) represent Tier 0 boundary systems. Because they handle the highest levels of domain authorization, physical threat vectors must be mitigated to the absolute maximum threshold:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Direct Memory Access (DMA) Defenses</xhtml:strong>: External interfaces (e.g., Thunderbolt, USB4, PCIe ExpressCard, FireWire) allow attached devices to bypass the OS kernel and read physical RAM contents directly via high-speed buses. Attackers use physical DMA exploitation devices (such as PCILeech) to dump memory-resident Kerberos TGT tickets, NTLM hashes, and LSA secrets:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Device Setup Class Blocking</xhtml:em>*: Disabling the SBP-2 setup class (<xhtml:code>{d48179be-ec20-11d1-b6b8-00c04fa372a7}</xhtml:code>) and the IEEE 1394 host controller class (<xhtml:code>{6bdd1fc1-810f-11d0-bec7-08002be2092f}</xhtml:code>) prevents Windows from binding drivers to FireWire storage and controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hardware ID Blocking</xhtml:em>*: Explicitly blocking hardware IDs <xhtml:code>PCI\CC_0C0A</xhtml:code> (Thunderbolt), <xhtml:code>PCI\CC_0C0010</xhtml:code> (1394 OHCI FireWire), <xhtml:code>PCI\CC_0607</xhtml:code> (CardBus), and <xhtml:code>PCI\CC_0605</xhtml:code> (PCMCIA) halts driver installation for unauthorized high-speed expansion buses at the PCI enumeration layer.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>BitLocker DMA Under Lock</xhtml:em>*: Enforcing <xhtml:code>DisableExternalDMAUnderLock</xhtml:code> blocks DMA device operations whenever the PAW workstation is locked, closing the physical window for drive-by attacks on unattended stations.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Tightened Enumeration Policy on PAWs</xhtml:em>
            <xhtml:em>: While standard enterprise endpoints might permit external DMA after user authentication, PAWs enforce a strict </xhtml:em>
            <xhtml:em>Block all</xhtml:em>* policy (<xhtml:code>DeviceEnumerationPolicy = 0</xhtml:code>). External peripherals whose drivers do not natively support DMA-remapping isolation are permanently prevented from accessing system memory.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Cold Boot Exploits &amp; RAM Decay</xhtml:strong>: Dynamic RAM retains memory contents for seconds or minutes following power loss, especially when cooled with aerosol duster or liquid nitrogen. In standard standby states (S1-S3), the RAM chips remain continuously powered and active. If a PAW is stolen or accessed while in standby, BitLocker master keys and volatile credentials can be read directly from memory. Disabling standby states forces the system to either remain active or transition to Hibernation (S4)/Shutdown, where RAM contents are encrypted on the BitLocker volume and protected by the TPM 2.0 PCR baseline. Enforcing a password on resume guarantees re-authentication upon wake.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>USB Exfiltration Protection</xhtml:strong>: Restricting write access on removable drives (<xhtml:code>RDVDenyWriteAccess</xhtml:code>) ensures administrative materials, directory backups, or sensitive credentials cannot be copied to unencrypted USB media. Setting <xhtml:code>RDVDenyCrossOrg = 0</xhtml:code> prevents cross-organization removable storage exemptions.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>1. Power Management (Disable Standby &amp; Require Wake Password)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Power Management\Sleep Settings</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow standby states (S1-S3) when sleeping (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Allow standby states (S1-S3) when sleeping (on battery)</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Require a password when a computer wakes (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Require a password when a computer wakes (on battery)</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
        </xhtml:p>
        <xhtml:h4>2. BitLocker Removable Storage &amp; DMA</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Disable new DMA devices when this computer is locked` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em />
        </xhtml:p>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption\Removable Data Drives</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Deny write access to removable drives not protected by BitLocker` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Check <xhtml:strong>Do not allow write access to devices configured in another organization</xhtml:strong> -&gt; <xhtml:strong>Disabled</xhtml:strong> (value 0 / False)</xhtml:p>
        <xhtml:h4>3. Device Installation Restrictions (Block SBP-2, 1394, Thunderbolt, and PCI Bridges)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Device Installation\Device Installation Restrictions</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Prevent installation of devices using drivers that match these device setup classes` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Click <xhtml:strong>Show...</xhtml:strong> and enter: <xhtml:em> `{d48179be-ec20-11d1-b6b8-00c04fa372a7}` </xhtml:em>
          <xhtml:code>{6bdd1fc1-810f-11d0-bec7-08002be2092f}</xhtml:code>
          <xhtml:em> Check </xhtml:em>
          <xhtml:em>Also apply to matching devices that are already installed</xhtml:em>
          <xhtml:em> -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (value 1 / True) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Prevent installation of devices that match any of these device IDs</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> Click </xhtml:em>
          <xhtml:em>Show...</xhtml:em>
          <xhtml:em> and enter: </xhtml:em>
          <xhtml:code>PCI\CC_0C0A</xhtml:code>
          <xhtml:em> `PCI\CC_0C0010` </xhtml:em>
          <xhtml:code>PCI\CC_0607</xhtml:code>
          <xhtml:em> `PCI\CC_0605` </xhtml:em> Check <xhtml:strong>Also apply to matching devices that are already installed</xhtml:strong> -&gt; <xhtml:strong>Enabled</xhtml:strong> (value 1 / True)</xhtml:p>
        <xhtml:h4>4. Kernel DMA Protection (Block All)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Enable Kernel DMA Protection` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Enumeration policy</xhtml:strong>: Set to <xhtml:strong>Block all</xhtml:strong> (value 0)</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally on the PAW to apply DMA, Sleep, Device Restriction, and BitLocker USB registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PawDMAPhysicalSecurity.ps1">Download Script: Set-PawDMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PawDMAPhysicalSecurity.ps1
# Description: Hardens local registry keys on PAWs to mitigate DMA attacks, disable standby sleep states, enforce wake password, restrict device classes/IDs, and block unencrypted USB writing.

Write-Host "Applying PAW DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Classes and Hardware IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String
Set-ItemProperty -Path $DenyClassPath -Name "2" -Value "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" -Type String

$DenyIdPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIdPath)) {
    New-Item -Path $DenyIdPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIdPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "3" -Value "PCI\CC_0607" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "4" -Value "PCI\CC_0605" -Type String
Write-Host "[+] Device installation blocks for SBP-2, 1394 host controllers, Thunderbolt, and PCI bridges enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA permanently for PAWs)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "PAW DMA and physical security settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local PAW DMA and physical security configuration:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-PawDMAPhysicalSecurity.ps1">Download Script: Test-PawDMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawDMAPhysicalSecurity.ps1
# Description: Audits local registry configuration for standby settings, wake password, DMA protection under lock, USB restrictions, and blocked device classes/IDs on PAWs.

Write-Host "--- Auditing PAW DMA and Physical Security ---" -ForegroundColor Cyan
$isCompliant = $true

# 1. Audit Standby Settings
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
$AcSleep = Get-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcSleep = Get-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcSleepVal = if ($AcSleep) { $AcSleep.ACSettingIndex } else { 1 }
$DcSleepVal = if ($DcSleep) { $DcSleep.DCSettingIndex } else { 1 }

$AcSleepColor = if ($AcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }
$DcSleepColor = if ($DcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Standby Sleep State (Plugged In) Setting: $($AcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $AcSleepColor
Write-Host "    - Standby Sleep State (On Battery) Setting: $($DcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $DcSleepColor

# 2. Audit Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
$AcWake = Get-ItemProperty -Path $WakePath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcWake = Get-ItemProperty -Path $WakePath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcWakeVal = if ($AcWake) { $AcWake.ACSettingIndex } else { 0 }
$DcWakeVal = if ($DcWake) { $DcWake.DCSettingIndex } else { 0 }

$AcWakeColor = if ($AcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }
$DcWakeColor = if ($DcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Wake Password Required (Plugged In): $($AcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $AcWakeColor
Write-Host "    - Wake Password Required (On Battery): $($DcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $DcWakeColor

# 3. Audit BitLocker Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
$DmaLock = Get-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -ErrorAction SilentlyContinue
$DmaLockVal = if ($DmaLock) { $DmaLock.DisableExternalDMAUnderLock } else { 0 }
$DmaLockColor = if ($DmaLockVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$CrossOrg = Get-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -ErrorAction SilentlyContinue
$CrossOrgVal = if ($CrossOrg) { $CrossOrg.RDVDenyCrossOrg } else { 1 }
$CrossOrgColor = if ($CrossOrgVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
$UsbWrite = Get-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -ErrorAction SilentlyContinue
$UsbWriteVal = if ($UsbWrite) { $UsbWrite.RDVDenyWriteAccess } else { 0 }
$UsbWriteColor = if ($UsbWriteVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Disable DMA Under Lock: $($DmaLockVal) (Required = 1)" -ForegroundColor $DmaLockColor
Write-Host "    - USB Deny Cross Org Removable Drives: $($CrossOrgVal) (Required = 0)" -ForegroundColor $CrossOrgColor
Write-Host "    - USB Unencrypted Write Block: $($UsbWriteVal) (Required = 1)" -ForegroundColor $UsbWriteColor

# 4. Audit Device Restriction Settings
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
$DenyDev = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -ErrorAction SilentlyContinue
$DenyDevVal = if ($DenyDev) { $DenyDev.DenyDeviceClasses } else { 0 }
$DenyDevColor = if ($DenyDevVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$DenyId = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -ErrorAction SilentlyContinue
$DenyIdVal = if ($DenyId) { $DenyId.DenyDeviceIDs } else { 0 }
$DenyIdColor = if ($DenyIdVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Prevent Device Setup Class Installation: $($DenyDevVal) (Required = 1)" -ForegroundColor $DenyDevColor
Write-Host "    - Prevent Device ID Installation: $($DenyIdVal) (Required = 1)" -ForegroundColor $DenyIdColor

$DenyClassPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses"
$Sbp2 = Get-ItemProperty -Path $DenyClassPath -Name "1" -ErrorAction SilentlyContinue
$Sbp2Val = if ($Sbp2) { $Sbp2."1" } else { "" }
$Sbp2Color = if ($Sbp2Val -eq "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { "Green" } else { $isCompliant = $false; "Red" }

$Host1394 = Get-ItemProperty -Path $DenyClassPath -Name "2" -ErrorAction SilentlyContinue
$Host1394Val = if ($Host1394) { $Host1394."2" } else { "" }
$Host1394Color = if ($Host1394Val -eq "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked SBP-2 Setup Class: '$($Sbp2Val)' (Required = '{d48179be-ec20-11d1-b6b8-00c04fa372a7}')" -ForegroundColor $Sbp2Color
Write-Host "    - Blocked 1394 Host Setup Class: '$($Host1394Val)' (Required = '{6bdd1fc1-810f-11d0-bec7-08002be2092f}')" -ForegroundColor $Host1394Color

$DenyIdPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs"
$DId1 = Get-ItemProperty -Path $DenyIdPath -Name "1" -ErrorAction SilentlyContinue
$DId1Val = if ($DId1) { $DId1."1" } else { "" }
$DId1Color = if ($DId1Val -eq "PCI\CC_0C0A") { "Green" } else { $isCompliant = $false; "Red" }

$DId2 = Get-ItemProperty -Path $DenyIdPath -Name "2" -ErrorAction SilentlyContinue
$DId2Val = if ($DId2) { $DId2."2" } else { "" }
$DId2Color = if ($DId2Val -eq "PCI\CC_0C0010") { "Green" } else { $isCompliant = $false; "Red" }

$DId3 = Get-ItemProperty -Path $DenyIdPath -Name "3" -ErrorAction SilentlyContinue
$DId3Val = if ($DId3) { $DId3."3" } else { "" }
$DId3Color = if ($DId3Val -eq "PCI\CC_0607") { "Green" } else { $isCompliant = $false; "Red" }

$DId4 = Get-ItemProperty -Path $DenyIdPath -Name "4" -ErrorAction SilentlyContinue
$DId4Val = if ($DId4) { $DId4."4" } else { "" }
$DId4Color = if ($DId4Val -eq "PCI\CC_0605") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked Device ID PCI\CC_0C0A: '$($DId1Val)' (Required = 'PCI\CC_0C0A')" -ForegroundColor $DId1Color
Write-Host "    - Blocked Device ID PCI\CC_0C0010: '$($DId2Val)' (Required = 'PCI\CC_0C0010')" -ForegroundColor $DId2Color
Write-Host "    - Blocked Device ID PCI\CC_0607: '$($DId3Val)' (Required = 'PCI\CC_0607')" -ForegroundColor $DId3Color
Write-Host "    - Blocked Device ID PCI\CC_0605: '$($DId4Val)' (Required = 'PCI\CC_0605')" -ForegroundColor $DId4Color

# 5. Audit Kernel DMA Protection Setting (Stricter for PAWs)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
$EnumPol = Get-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -ErrorAction SilentlyContinue
$EnumPolVal = if ($EnumPol) { $EnumPol.DeviceEnumerationPolicy } else { 2 }
$EnumPolColor = if ($EnumPolVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Kernel DMA Protection Policy: $($EnumPolVal) (Required = 0 [Block all])" -ForegroundColor $EnumPolColor

# 6. Final Compliance Assessment
if ($isCompliant) {
    Write-Host "[+] Audit Result: SECURE - PAW DMA and physical security controls are fully compliant." -ForegroundColor Green
} else {
    Write-Host "[-] Audit Result: VULNERABLE - One or more PAW DMA or physical security settings do not meet baseline requirements." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PawDMAPhysicalSecurity.ps1
# Description: Hardens local registry keys on PAWs to mitigate DMA attacks, disable standby sleep states, enforce wake password, restrict device classes/IDs, and block unencrypted USB writing.

Write-Host "Applying PAW DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Classes and Hardware IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String
Set-ItemProperty -Path $DenyClassPath -Name "2" -Value "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" -Type String

$DenyIdPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIdPath)) {
    New-Item -Path $DenyIdPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIdPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "3" -Value "PCI\CC_0607" -Type String
Set-ItemProperty -Path $DenyIdPath -Name "4" -Value "PCI\CC_0605" -Type String
Write-Host "[+] Device installation blocks for SBP-2, 1394 host controllers, Thunderbolt, and PCI bridges enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA permanently for PAWs)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "PAW DMA and physical security settings applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-012" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-012] Enable WDAC Driver Blocklist</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10, Windows 11 (Enterprise and Professional editions)</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-wdac-driver-blocklist.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Attackers frequently employ "Bring Your Own Vulnerable Driver" (BYOVD) attacks to bypass Windows kernel protections on high-value administrative assets like Privileged Access Workstations (PAWs). In a BYOVD attack, an adversary with administrative privileges installs a legitimate, cryptographically signed third-party driver that contains a known, exploitable vulnerability. The attacker then exploits this vulnerability to execute arbitrary code with kernel privileges, allowing them to disable security agents, dump LSASS memory, or tamper with system integrity.</xhtml:p>
        <xhtml:p>Enforcing the <xhtml:strong>Microsoft Vulnerable Driver Blocklist</xhtml:strong> via Windows Defender Application Control (WDAC) prevents known vulnerable or malicious drivers from loading in kernel space. By restricting the WDAC policy to <xhtml:strong>Kernel Mode Code Integrity (KMCI) only</xhtml:strong> (omitting user-mode enforcement), the control shields the system kernel from driver-based exploits on administrative hosts without introducing administrative overhead or blocking standard user-mode admin applications.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce the driver blocklist across all PAWs, you can deploy the Microsoft recommended block rules as a custom WDAC policy.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Download the Microsoft recommended driver block rules XML from the official Microsoft documentation.</xhtml:li>
          <xhtml:li>Edit the XML to ensure it operates in <xhtml:strong>Audit Mode</xhtml:strong> first, then convert the XML configuration into a binary format:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`powershell</xhtml:li>
          <xhtml:li>ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\DriverBlocklist.xml" -BinaryFilePath "C:\WDAC\SIPolicy.p7b"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the compiled <xhtml:code>SIPolicy.p7b</xhtml:code> file to a secure local path on all target PAWs (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or a share.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the PAWs OU (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the local or network path to the policy file (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>).</xhtml:li>
          <xhtml:li>To ensure the built-in system driver blocklist is active on modern builds, configure the following registry setting via Group Policy Preferences:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Path</xhtml:em>*: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\CI\Config</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>VulnerableDriverBlocklistEnable</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enable the Vulnerable Driver Blocklist registry key and ensure proper configuration.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DriverBlocklist.ps1">Download Script: Configure-DriverBlocklist.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DriverBlocklistStatus.ps1">Download Script: Get-DriverBlocklistStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DriverBlocklistStatus.ps1
# Description: Audits the configuration of the Microsoft Vulnerable Driver Blocklist and HVCI state.

Write-Host "--- Auditing Vulnerable Driver Blocklist ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Check registry value
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (Test-Path $RegPath) {
    $RegValue = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $RegValue -and $RegValue.$ValueName -eq 1) {
        Write-Host "[+] Vulnerable Driver Blocklist is enabled in the registry." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Vulnerable Driver Blocklist is disabled or not set in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Code Integrity Config registry key does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Check HVCI Status
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: The Vulnerable Driver Blocklist is not fully secured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: The Vulnerable Driver Blocklist and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7012" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-014" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-014] Configure Early Launch Antimalware (ELAM) Policy for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs). <xhtml:em>(For Domain Controllers, refer to [REQ-DC-156](../02-domain-controllers/configure-elam.md); for Tier 2 Client Workstations and Member Servers, refer to [REQ-END-028](../08-endpoints/configure-elam.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise, Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-elam.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated administrative bastions that operate at the pinnacle of the enterprise security architecture (Tier 0). Compromise of a PAW grants adversaries the credentials necessary to commandeer identity infrastructure, cloud tenants, and enterprise directory data.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the dedicated PAW hardening GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Early Launch Antimalware</xhtml:code>
          </xhtml:li>
          <xhtml:li>In the right pane, double-click <xhtml:strong>Boot-Start Driver Initialization Policy</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the <xhtml:strong>Choose the boot-start drivers that can be initialized</xhtml:strong> dropdown, select:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Good and unknown</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated <xhtml:strong>PAW</xhtml:strong> Organizational Unit (<xhtml:code>OU=PAWs,OU=Tier0,DC=domain,DC=com</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally on PAWs to configure the tightened ELAM policy.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-ElamPolicy.ps1">Download Script: Configure-ElamPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-ElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver load policy on the local system.

Write-Host "Applying ELAM Boot-Start driver initialization policy (Tightened for PAWs)..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good and unknown' (Value = 1)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-ElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver load policy on the local system.

Write-Host "Applying ELAM Boot-Start driver initialization policy (Tightened for PAWs)..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good and unknown' (Value = 1)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7014" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-015" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-015] Configure Secure Printing and Print Spooler Policies for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-printing-and-spooler.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Print Spooler service (<xhtml:code>Spooler</xhtml:code>) has been a recurring source of critical privilege escalation and coercion exploits (e.g., the PrintNightmare family).</xhtml:p>
        <xhtml:p>To secure Privileged Access Workstations (PAWs), which host highly privileged Tier 0 credentials: 1. <xhtml:strong>Disable the Print Spooler</xhtml:strong>: PAWs should never act as print servers or need print capabilities. Disabling the <xhtml:code>Spooler</xhtml:code> service completely eliminates this massive attack surface. 2. <xhtml:strong>Point and Print Restrictions</xhtml:strong>: As a defense-in-depth fallback, restricting print driver installations and updates to Administrators ensures that even if the spooler service is temporarily enabled for maintenance, standard users cannot load arbitrary, untrusted drivers.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Disable the Print Spooler Service</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO applied to your PAWs (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Print Spooler</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and select <xhtml:strong>Disabled</xhtml:strong>. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Restrict Point and Print Driver Installations</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Printers</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Limits print driver installation to Administrators</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set it to <xhtml:strong>Enabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to disable the Print Spooler service and enforce driver restrictions.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PrintingAndSpooler.ps1">Download Script: Configure-PrintingAndSpooler.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PrintingAndSpooler.ps1
# Description: Disables the Print Spooler service and configures Point and Print driver installation restrictions on the local PAW.

Write-Host "Hardening Print Spooler and Printer configurations for PAWs..." -ForegroundColor Cyan

# 1. Disable the Print Spooler Service
if (Get-Service -Name "Spooler" -ErrorAction SilentlyContinue) {
    Set-Service -Name "Spooler" -StartupType Disabled -Confirm:$false
    Stop-Service -Name "Spooler" -Force -Confirm:$false
    Write-Host "[+] Print Spooler service has been stopped and disabled." -ForegroundColor Green
} else {
    Write-Host "[+] Print Spooler service not found on local machine." -ForegroundColor Gray
}

# 2. Limit Print Driver Installation to Administrators (Defense-in-Depth)
$PrinterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
if (-not (Test-Path $PrinterPath)) {
    New-Item -Path $PrinterPath -Force | Out-Null
}
Set-ItemProperty -Path $PrinterPath -Name "RestrictDriverInstallationToAdministrators" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Print driver installation restricted to Administrators." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit these printer security configurations on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PrintingAndSpoolerStatus.ps1">Download Script: Get-PrintingAndSpoolerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PrintingAndSpoolerStatus.ps1
# Description: Audits print spooler status and Point and Print configurations on the local PAW.

Write-Host "--- Auditing PAW Secure Printing and Spooler Hardening ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# 1. Audit Spooler Service Startup Type
$Service = Get-Service -Name "Spooler" -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    # Check StartupType
    $StartupType = (Get-CimInstance -ClassName Win32_Service -Filter "Name='Spooler'").StartMode
    # StartMode can be "Disabled", "Manual", "Auto"
    $Color = if ($StartupType -eq "Disabled") { "Green" } else { "Red" }
    Write-Host "  [-] Print Spooler Service Startup: $StartupType (Expected: Disabled)" -ForegroundColor $Color
    if ($StartupType -ne "Disabled") {
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [+] Print Spooler Service is not present on this machine." -ForegroundColor Green
}

# 2. Audit Point and Print Registry Restriction
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
$Name = "RestrictDriverInstallationToAdministrators"
$Expected = 1

if (Test-Path $Path) {
    $Reg = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue
    $Val = $Reg.$Name
    if ($Val -eq $Expected) {
        Write-Host "  [+] Path $($Path) | $($Name): $Val (Expected: $Expected)" -ForegroundColor Green
    } else {
        Write-Host "  [!] MISMATCH: Path $($Path) | $($Name): $Val (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] NOT FOUND: Path $($Path) (Expected: $Name = $Expected)" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PrintingAndSpooler.ps1
# Description: Disables the Print Spooler service and configures Point and Print driver installation restrictions on the local PAW.

Write-Host "Hardening Print Spooler and Printer configurations for PAWs..." -ForegroundColor Cyan

# 1. Disable the Print Spooler Service
if (Get-Service -Name "Spooler" -ErrorAction SilentlyContinue) {
    Set-Service -Name "Spooler" -StartupType Disabled -Confirm:$false
    Stop-Service -Name "Spooler" -Force -Confirm:$false
    Write-Host "[+] Print Spooler service has been stopped and disabled." -ForegroundColor Green
} else {
    Write-Host "[+] Print Spooler service not found on local machine." -ForegroundColor Gray
}

# 2. Limit Print Driver Installation to Administrators (Defense-in-Depth)
$PrinterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
if (-not (Test-Path $PrinterPath)) {
    New-Item -Path $PrinterPath -Force | Out-Null
}
Set-ItemProperty -Path $PrinterPath -Name "RestrictDriverInstallationToAdministrators" -Value 1 -Type DWord -ErrorAction Stop
Write-Host "[+] Print driver installation restricted to Administrators." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7015" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-016" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-016] Configure Untrusted Font Blocking for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-untrusted-font-blocking.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Font files (TrueType, OpenType, and others) are highly complex formats that require advanced parsing logic. Historically, font parsing in Windows was performed by the Graphics Device Interface (GDI) within the operating system kernel. Vulnerabilities in the kernel-mode font parser (such as buffer overflows or remote code execution) have been frequently exploited by threat actors to execute arbitrary code with kernel-level privileges.</xhtml:p>
        <xhtml:p>Enabling Untrusted Font Blocking limits the attack surface of the graphics subsystem on Privileged Access Workstations (PAWs): 1. <xhtml:strong>Kernel Attack Surface Reduction</xhtml:strong>: Restricting the system to only load trusted fonts installed in the <xhtml:code>%windir%\Fonts</xhtml:code> system directory prevents the processing of malicious, web-delivered, or embedded font files. 2. <xhtml:strong>Mitigation of Document-Based Exploits</xhtml:strong>: Prevents malicious font files embedded in administrative documents, scripts, or web tools from triggering parsing vulnerabilities in the context of high-privileged administrative accounts.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Mitigation Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Untrusted Font Blocking</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Mitigation Options</xhtml:em>*: <xhtml:code>Block untrusted fonts and log events</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the PAW Organizational Unit (OU) containing the target workstations.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone systems or during reference image build phases.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-UntrustedFontBlocking.ps1">Download Script: Configure-UntrustedFontBlocking.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events on PAWs.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-UntrustedFontBlockingStatus.ps1">Download Script: Get-UntrustedFontBlockingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-UntrustedFontBlockingStatus.ps1
# Description: Checks the current configuration state of Untrusted Font Blocking registry setting on PAWs.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ExpectedValue = "1000000000000"

Write-Host "Auditing hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (Test-Path $RegPath) {
    $value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $value -and $value.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. Untrusted fonts are blocked and logged ($($ValueName) = $($ExpectedValue))." -ForegroundColor Green
        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. Untrusted fonts are not configured to block and log." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events on PAWs.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7016" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-017" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-017] Configure svchost.exe Mitigation Options for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs). <xhtml:em>(For Domain Controllers and Domain Member Servers, refer to [REQ-DC-029](../02-domain-controllers/configure-svchost-mitigation.md); for Tier 2 Client Workstations, refer to [REQ-END-030](../08-endpoints/configure-svchost-mitigation.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (1903 and above), Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-svchost-mitigation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) host the most sensitive administrative credentials in an Active Directory environment, including Tier 0 Domain Admin Kerberos tickets, directory service RPC sessions, and PKI private key operations. Because PAWs are dedicated, single-purpose administrative endpoints, securing the Service Host (<xhtml:code>svchost.exe</xhtml:code>) process is critical to preventing kernel-level security evasion, process injection, and credential theft.</xhtml:p>
        <xhtml:p>Adversaries attempting to compromise administrative sessions frequently target <xhtml:code>svchost.exe</xhtml:code>: 1. <xhtml:strong>Process Injection &amp; Credential Harvesting</xhtml:strong>: Infiltrating an administrative session by injecting into a high-privilege <xhtml:code>svchost.exe</xhtml:code> process (<xhtml:code>CreateRemoteThread</xhtml:code>, <xhtml:code>QueueUserAPC</xhtml:code>, <xhtml:code>SetThreadContext</xhtml:code>) allows attackers to execute shellcode within the <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code> security context, evading endpoint monitoring and attempting to access memory spaces holding privileged administrative tokens. 2. <xhtml:strong>Reflective DLL Loading &amp; Dynamic Code Execution</xhtml:strong>: Advanced persistent threat (APT) frameworks execute memory-only payloads by allocating executable memory (<xhtml:code>VirtualAlloc</xhtml:code> with <xhtml:code>PAGE_EXECUTE_READWRITE</xhtml:code>) to bypass disk-based file scanners. 3. <xhtml:strong>Ghost Service Implants (MITRE ATT&amp;CK T1574.002)</xhtml:strong>: Dropping unsigned service DLLs and registering them under legitimate <xhtml:code>svchost.exe</xhtml:code> service groups to gain persistent administrative access.</xhtml:p>
        <xhtml:p>Enabling <xhtml:code>svchost.exe</xhtml:code> mitigation options on PAWs restricts the behavior of every <xhtml:code>svchost.exe</xhtml:code> process through kernel-level mitigation policies: <xhtml:em> </xhtml:em>
          <xhtml:em>Microsoft-Only Binary Enforcement (`PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON`)</xhtml:em>
          <xhtml:em>: Requires all binaries and dynamic-link libraries (DLLs) loaded into `svchost.exe` to be digitally signed by Microsoft. This prevents attackers from injecting custom, unsigned malicious DLLs into `svchost.exe` instances to tamper with administrative service processes. Any attempt to load non-Microsoft code is blocked with `STATUS_INVALID_IMAGE_HASH` (`0xC0000428`). </xhtml:em>
          <xhtml:strong>Dynamic Code Execution Blocking (`PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON`)</xhtml:strong>: Disallows the generation and execution of dynamic code within <xhtml:code>svchost.exe</xhtml:code> processes. This neutralizes in-memory shellcode execution, JIT compilation abuse, and typical process hollowing attack vectors. <xhtml:em> </xhtml:em>
          <xhtml:em>Service Host Isolation</xhtml:em>*: On modern Windows 10/11 Enterprise systems with more than 3.5 GB of RAM, services run in separate, dedicated <xhtml:code>svchost.exe</xhtml:code> processes, ensuring each administrative service host is strictly isolated and independently enforced.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a PAW or Domain Controller.</xhtml:li>
          <xhtml:li>Edit the dedicated PAW hardening GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Service Control Manager Settings\Security Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Enable svchost.exe mitigation options</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated <xhtml:strong>PAW</xhtml:strong> Organizational Unit (<xhtml:code>OU=PAW,OU=Tier0,DC=contoso,DC=com</xhtml:code>).</xhtml:li>
          <xhtml:li>Reboot the target PAW systems to ensure the mitigation policy is actively enforced across all system services.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone PAWs or during initial reference image provisioning.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-SvchostMitigation.ps1">Download Script: Configure-SvchostMitigation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code on PAWs.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options for PAWs..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows 11)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows 10 1903+ or Windows 11)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options on PAW: $($_.Exception.Message)"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SvchostMitigationStatus.ps1">Download Script: Get-SvchostMitigationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SvchostMitigationStatus.ps1
# Description: Audits the configuration state of svchost.exe mitigation options on PAWs.

[CmdletBinding()]
param()

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ExpectedValue = 1

Write-Host "Auditing hardening requirement: Configure svchost.exe mitigation options on PAW..." -ForegroundColor Cyan

$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "Audit Result: Non-Applicable / Unsupported. OS build $($osBuild) precedes the introduction of svchost mitigation policy (requires Windows 10 1903+ or Windows 11)."
    exit 1
}

if (Test-Path -Path $RegPath) {
    $item = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $item -and $item.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. svchost.exe mitigation policy is enabled in registry ($($RegPath)\$($ValueName) = 1)." -ForegroundColor Green

        # Optional check for running svchost processes
        $svchostProcesses = Get-Process -Name "svchost" -ErrorAction SilentlyContinue
        if ($svchostProcesses) {
            Write-Host "Found $($svchostProcesses.Count) running svchost.exe process instances. Process mitigation flags are enforced dynamically at process spawn by the Service Control Manager." -ForegroundColor Gray
        }

        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. svchost.exe mitigation options are disabled or not configured ($($RegPath)\$($ValueName))." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code on PAWs.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options for PAWs..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows 11)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows 10 1903+ or Windows 11)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options on PAW: $($_.Exception.Message)"
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7017" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-018" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-018] Enable Kernel-Mode Hardware-Enforced Stack Protection for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 11 (and above) Enterprise/Professional</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-kernel-shadow-stacks.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kernel-mode Hardware-enforced Stack Protection uses CPU hardware features to protect the operating system kernel from memory corruption exploits, specifically Return-Oriented Programming (ROP) attacks.</xhtml:p>
        <xhtml:p>On highly critical endpoints such as Privileged Access Workstations (PAWs), attackers aim to achieve kernel-mode execution to subvert administrative separation controls, bypass Endpoint Detection and Response (EDR) software, and extract domain credential secrets from isolated zones.</xhtml:p>
        <xhtml:p>Intel Control-flow Enforcement Technology (CET) and AMD Shadow Stack technologies create a separate, hardware-secured copy of the call stack (the "shadow stack"). Before returning from a function, the CPU compares the return address on the standard stack with the address stored on the hardware-secured shadow stack. If a mismatch is detected, the processor terminates the thread or crashes the system, neutralizing control-flow hijacking attempts.</xhtml:p>
        <xhtml:p>Deploying Kernel-mode Hardware-enforced Stack Protection on PAWs guarantees that the administrative gateway machines remain resilient against advanced kernel exploits.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the appropriate PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn On Virtualization Based Security` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Kernel-level shadow stacks</xhtml:em>
            <xhtml:em> -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (or set registry <xhtml:code>Enabled</xhtml:code> = <xhtml:code>1</xhtml:code>)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the registry and activate Kernel-mode Hardware-enforced Stack Protection.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enable-PawKernelShadowStacks.ps1">Download Script: Enable-PawKernelShadowStacks.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enable-PawKernelShadowStacks.ps1
# Description: Configures HKLM registry to enable Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks) for PAWs.

Write-Host "Enabling Kernel-mode Hardware-enforced Stack Protection for PAWs..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "Enabled" -Value 1 -Type DWord
Write-Host "[+] Registry setting for PAW Kernel Shadow Stacks enabled. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the state of Kernel-mode Hardware-enforced Stack Protection:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawKernelShadowStacks.ps1">Download Script: Test-PawKernelShadowStacks.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawKernelShadowStacks.ps1
# Description: Audits the registry status of Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks) for PAWs.

Write-Host "--- Auditing PAW Kernel-mode Hardware-enforced Stack Protection ---" -ForegroundColor Cyan

$script:Vulnerable = $false
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

# Check registry value
$val = Get-ItemProperty -Path $RegPath -Name "Enabled" -ErrorAction SilentlyContinue
$actual = if ($val) { $val.Enabled } else { "" }

if ($actual -eq 1) {
    Write-Host "    - Registry Setting: KernelShadowStacks Enabled | Actual: '1' (Expected: '1')" -ForegroundColor Green
} else {
    $script:Vulnerable = $true
    Write-Host "    - Registry Setting: KernelShadowStacks Enabled | Actual: '$actual' (Expected: '1')" -ForegroundColor Red
}

# Verify VBS dependency is met
try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    if ($DG.VirtualizationBasedSecurityStatus -eq 2) {
        Write-Host "    - VBS Status: Running" -ForegroundColor Green
    } else {
        $script:Vulnerable = $true
        Write-Host "    - VBS Status: Not Running (VBS is required for Kernel Shadow Stacks)" -ForegroundColor Red
    }
} catch {
    $script:Vulnerable = $true
    Write-Host "    - DeviceGuard WMI class query failed. VBS is likely disabled." -ForegroundColor Red
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enable-PawKernelShadowStacks.ps1
# Description: Configures HKLM registry to enable Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks) for PAWs.

Write-Host "Enabling Kernel-mode Hardware-enforced Stack Protection for PAWs..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "Enabled" -Value 1 -Type DWord
Write-Host "[+] Registry setting for PAW Kernel Shadow Stacks enabled. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7018" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-019" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-019] Harden Network Parameters and Disable Legacy Name Resolution</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/harden-network-and-name-resolution.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Legacy name resolution protocols and insecure default network configurations are heavily targeted by attackers for credential harvesting and man-in-the-middle (MitM) positioning:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Legacy Name Resolution (LLMNR / NetBIOS)</xhtml:strong>: LLMNR and NBT-NS serve as fallback protocols when DNS resolution fails. When a host queries an unresolvable name, it broadcasts requests over the local subnet. An attacker can spoof responses (e.g., using Responder) to capture NTLMv2 hashes or perform authentication relay attacks. NetBIOS name release requests can be forged to disrupt local names unless protected.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>NetBIOS Node Type and Name Release</xhtml:strong>: Setting the Node Type to P-node (point-to-point, value 2) disables broadcast resolution fallbacks. Enabling name release protection (<xhtml:code>NoNameReleaseOnDemand</xhtml:code>) prevents attackers from spoofing name release requests to deregister local names.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>ICMP Redirects</xhtml:strong>: ICMP redirect packets can be used by an attacker on the same subnet to dynamically redirect routing for specific hosts through the attacker's machine, enabling full MitM packet sniffing and modification. Disabling ICMP redirects prevents this vector.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>IP Source Routing</xhtml:strong>: Source routing allows a sender to specify the exact network path a packet should follow. This is commonly abused to bypass firewall routing rules or establish communication paths that violate network segment isolation.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Default IPv6 DNS Servers</xhtml:strong>: Disabling default IPv6 DNS servers prevents automated fallback to unauthenticated, dynamic local IPv6 DNS servers advertised by rogue routers or malicious tools (like mitm6), which would otherwise redirect query traffic and coerce NTLM or Kerberos authentication.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Web Proxy Auto-Discovery (WPAD)</xhtml:strong>: Disabling WPAD removes another name resolution mechanism that Responder exploits to harvest credentials. By disabling the <xhtml:code>WinHttpAutoProxySvc</xhtml:code> service and configuring <xhtml:code>WpadOverride = 1</xhtml:code>, the workstation is protected from rogue web proxy configurations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Restrict Net Session Enumeration (NetCease)</xhtml:strong>: By default, any authenticated domain user can query session information from remote hosts. Attackers utilize session enumeration to locate high-privileged user sessions (e.g., Domain Admins) across the network. Hardening the <xhtml:code>SrvsvcSessionInfo</xhtml:code> default security descriptor blocks this remote reconnaissance.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Configure DNS Client Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\DNS Client</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off Multicast Name Resolution` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Configure multicast DNS (mDNS) protocol` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off default IPv6 DNS Servers` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Configure Network Connections Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\Network Connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit use of Internet Connection Sharing on your DNS domain network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit installation and configuration of Network Bridge on your DNS domain network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Require domain users to elevate when setting a network's location` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Configure Windows Connection Manager Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\Windows Connection Manager</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Minimize the number of simultaneous connections to the Internet or a Windows Domain` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>3 = Prevent Wi-Fi when on Ethernet</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit connection to non-domain networks when connected to domain authenticated network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 4: Configure WLAN Settings (WiFi Sense)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\WLAN Service\WLAN Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 5: Configure Spooler and HTTP Printing Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off downloading of print drivers over HTTP` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off printing over HTTP` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 6: Configure Network Access Security settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Network access: Restrict anonymous access to Named Pipes and Shares` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 7: Disable WinHTTP WPAD Service</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Scroll to <xhtml:strong>WinHTTP Web Proxy Auto-Discovery Service</xhtml:strong>, select <xhtml:strong>Define this service setting</xhtml:strong>, and set the service startup mode to <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 8: Configure Registry Network settings via GPO Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> and select <xhtml:strong>New -&gt; Registry Item</xhtml:strong> for each of the following:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>NetBIOS Name Release Protection</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Netbt\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>NoNameReleaseOnDemand</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>NetBIOS P-Node Type</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Netbt\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>NodeType</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable ICMP Redirects</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>EnableICMPRedirect</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>0</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable IP Source Routing (IPv4)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>DisableIPSourceRouting</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable IP Source Routing (IPv6)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>DisableIPSourceRouting</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable WPAD Override (User Preference)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>WpadOverride</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Restrict Net Session Enumeration (NetCease SDDL)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>SrvsvcSessionInfo</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_BINARY</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: Generate via SDDL <xhtml:code>D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:h4>Step 9: Disable NetBIOS (via DHCP Scope Options)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>DHCP Management Console</xhtml:strong> (<xhtml:code>dhcpmgmt.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Under Scope Options, select <xhtml:strong>Configure Options</xhtml:strong>.</xhtml:li>
          <xhtml:li>Add <xhtml:strong>Option 043 (Vendor Specific Info)</xhtml:strong> and set the NetBIOS over TCP/IP value to <xhtml:code>0x2</xhtml:code> (Disable NetBIOS over TCP/IP).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to disable legacy resolution and enforce secure TCP/IP registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PawNetworkHardening.ps1">Download Script: Set-PawNetworkHardening.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PawNetworkHardening.ps1
# Description: Configures local registry keys to disable LLMNR/NetBIOS, harden TCP/IP stack, prevent dual-homing, block hotspot auto-connect, print driver web downloads, HTTP printing, and limit anonymous share access on PAWs.

Write-Host "Applying network and name resolution hardening..." -ForegroundColor Cyan

# Helper to configure registry keys
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}


# 1. Disable LLMNR, mDNS, and default IPv6 DNS Servers
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnableMulticast" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnablemDNS" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "DisableIPv6DefaultDnsServers" 1
Write-Host "[+] LLMNR (Multicast Name Resolution), mDNS, and default IPv6 DNS Servers disabled." -ForegroundColor Green

# 2. Configure NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
if (-not (Test-Path $NetbtPath)) {
    New-Item -Path $NetbtPath -Force | Out-Null
}
Set-ItemProperty -Path $NetbtPath -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord
Set-ItemProperty -Path $NetbtPath -Name "NodeType" -Value 2 -Type DWord
Write-Host "[+] NetBIOS name release protection and P-node type configured." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all active adapters
Write-Host "[+] Disabling NetBIOS on all active network adapters..." -ForegroundColor Gray
$Adapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue | Where-Object { $_.IPEnabled -eq $true }
if ($Adapters) {
    foreach ($Adapter in $Adapters) {
        Invoke-CimMethod -InputObject $Adapter -MethodName SetTCPIPNetBIOS -Arguments @{ TcpipNetbiosOptions = 2 } | Out-Null
    }
    Write-Host "    NetBIOS disabled on active network interfaces." -ForegroundColor Green
}

# 4. Harden TCP/IP Parameters
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "EnableICMPRedirect" 0
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv4 TCP/IP parameter redirects and source routing disabled." -ForegroundColor Green

Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv6 TCP/IP parameter source routing disabled." -ForegroundColor Green

# 5. Prevent Network Connection Sharing and Dual-Homing Bridging
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_ShowSharedAccessUI" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_AllowNetBridge_NLA" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_StdDomainUserSetLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fMinimizeConnections" 3
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fBlockNonDomain" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config" "AutoConnectAllowedOEM" 0
Write-Host "[+] Network connections, sharing, bridging, elevation, and hotspot settings configured." -ForegroundColor Green

# 6. Printing Spooler Web Downloads and HTTP printing block
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableWebPnPDownload" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Write-Host "[+] Printing spooler HTTP and Web service options disabled." -ForegroundColor Green

# 7. Restrict anonymous access to SAM and Named Pipes/Shares
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" "RestrictNullSessAccess" 1
Write-Host "[+] Anonymous null session share access restricted." -ForegroundColor Green

# 8. Disable WPAD
Write-Host "[+] Disabling WinHTTP Auto-Proxy service..." -ForegroundColor Gray
Set-Service -Name "WinHttpAutoProxySvc" -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name "WinHttpAutoProxySvc" -Force -ErrorAction SilentlyContinue

$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
if (-not (Test-Path $WpadPath)) {
    New-Item -Path $WpadPath -Force | Out-Null
}
Set-ItemProperty -Path $WpadPath -Name "WpadOverride" -Value 1 -Type DWord -Force
Write-Host "[+] WPAD auto-detection disabled in user preferences registry." -ForegroundColor Green

# 9. Restrict Net Session Enumeration (NetCease SDDL)
Write-Host "[+] Restricting Net Session Enumeration..." -ForegroundColor Gray
try {
    $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)")
    $BinaryForm = New-Object byte[] $SD.BinaryLength
    $SD.GetBinaryForm($BinaryForm, 0)
    $LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
    if (-not (Test-Path $LanmanSecPath)) {
        New-Item -Path $LanmanSecPath -Force | Out-Null
    }
    Set-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -Value $BinaryForm -Type Binary -Force
    Write-Host "[+] Net Session Enumeration restricted to Admins/Operators/Power Users." -ForegroundColor Green
} catch {
    Write-Error "    Failed to apply Net Session Enumeration restrictions: $($_.Exception.Message)"
}

Write-Host "Network and name resolution hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the network and name resolution status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawNetworkHardeningStatus.ps1">Download Script: Test-PawNetworkHardeningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawNetworkHardeningStatus.ps1
# Description: Audits LLMNR, NetBIOS parameters, NetBIOS adapter state, TCP/IP parameters, and print/network connection options on PAWs.

Write-Host "--- Auditing Network and Name Resolution Baseline ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to audit registry properties
function Test-RegistryValue ($path, $name, $expectedValue) {
    $val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    $color = "Red"
    if ($actual -eq $expectedValue) {
        $color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expectedValue')" -ForegroundColor $color
}


# 1. Audit LLMNR, mDNS, and default IPv6 DNS Servers
$DnsPath = "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient"
Test-RegistryValue $DnsPath "EnableMulticast" 0
Test-RegistryValue $DnsPath "EnablemDNS" 0
Test-RegistryValue $DnsPath "DisableIPv6DefaultDnsServers" 1

# 2. Audit NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
Test-RegistryValue $NetbtPath "NoNameReleaseOnDemand" 1
Test-RegistryValue $NetbtPath "NodeType" 2

# 3. Audit TCP/IP Parameters
$TcpipPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
Test-RegistryValue $TcpipPath "EnableICMPRedirect" 0
Test-RegistryValue $TcpipPath "DisableIPSourceRouting" 2

$Tcpip6Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
Test-RegistryValue $Tcpip6Path "DisableIPSourceRouting" 2

# 4. Audit Connection Sharing &amp; Dual-Homing Settings
$NetConnPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections"
Test-RegistryValue $NetConnPath "NC_ShowSharedAccessUI" 0
Test-RegistryValue $NetConnPath "NC_AllowNetBridge_NLA" 0
Test-RegistryValue $NetConnPath "NC_StdDomainUserSetLocation" 1

$WcmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy"
Test-RegistryValue $WcmPath "fMinimizeConnections" 3
Test-RegistryValue $WcmPath "fBlockNonDomain" 1

$WifiPath = "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config"
Test-RegistryValue $WifiPath "AutoConnectAllowedOEM" 0

# 5. Audit HTTP Print Options
$PrinterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
Test-RegistryValue $PrinterPath "DisableWebPnPDownload" 1
Test-RegistryValue $PrinterPath "DisableHTTPPrinting" 1

# 6. Audit Null Session Share Restrict
$ServerPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
Test-RegistryValue $ServerPath "RestrictNullSessAccess" 1

# 7. Audit WPAD Service and Registry Override
$WpadSvc = Get-Service -Name "WinHttpAutoProxySvc" -ErrorAction SilentlyContinue
if ($null -ne $WpadSvc) {
    if ($WpadSvc.StartType -eq "Disabled") {
        Write-Host "    - WPAD Service State: Disabled (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: WPAD Service StartType is $($WpadSvc.StartType) (Expected: Disabled)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}
$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
Test-RegistryValue $WpadPath "WpadOverride" 1

# 8. Audit Net Session Enumeration (NetCease)
$LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
if (Test-Path $LanmanSecPath) {
    $SrvsvcSessionInfo = (Get-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -ErrorAction SilentlyContinue).SrvsvcSessionInfo
    if ($null -ne $SrvsvcSessionInfo) {
        try {
            $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, $SrvsvcSessionInfo, 0)
            $Sddl = $SD.GetSddlForm("Dacl")
            if ($Sddl -eq "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)") {
                Write-Host "    - Net Session Enumeration Security Descriptor: Hardened (Secure)" -ForegroundColor Green
            } else {
                Write-Host "    - VULNERABLE: Net Session Enumeration Security Descriptor is '$Sddl' (Expected: 'D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)')" -ForegroundColor Red
                $script:Vulnerable = $true
            }
        } catch {
            Write-Host "    - VULNERABLE: Failed to parse Net Session Enumeration security descriptor." -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: SrvsvcSessionInfo registry value not found." -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - VULNERABLE: LanmanServer\DefaultSecurity path not found." -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PawNetworkHardening.ps1
# Description: Configures local registry keys to disable LLMNR/NetBIOS, harden TCP/IP stack, prevent dual-homing, block hotspot auto-connect, print driver web downloads, HTTP printing, and limit anonymous share access on PAWs.

Write-Host "Applying network and name resolution hardening..." -ForegroundColor Cyan

# Helper to configure registry keys
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}


# 1. Disable LLMNR, mDNS, and default IPv6 DNS Servers
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnableMulticast" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnablemDNS" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "DisableIPv6DefaultDnsServers" 1
Write-Host "[+] LLMNR (Multicast Name Resolution), mDNS, and default IPv6 DNS Servers disabled." -ForegroundColor Green

# 2. Configure NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
if (-not (Test-Path $NetbtPath)) {
    New-Item -Path $NetbtPath -Force | Out-Null
}
Set-ItemProperty -Path $NetbtPath -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord
Set-ItemProperty -Path $NetbtPath -Name "NodeType" -Value 2 -Type DWord
Write-Host "[+] NetBIOS name release protection and P-node type configured." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all active adapters
Write-Host "[+] Disabling NetBIOS on all active network adapters..." -ForegroundColor Gray
$Adapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue | Where-Object { $_.IPEnabled -eq $true }
if ($Adapters) {
    foreach ($Adapter in $Adapters) {
        Invoke-CimMethod -InputObject $Adapter -MethodName SetTCPIPNetBIOS -Arguments @{ TcpipNetbiosOptions = 2 } | Out-Null
    }
    Write-Host "    NetBIOS disabled on active network interfaces." -ForegroundColor Green
}

# 4. Harden TCP/IP Parameters
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "EnableICMPRedirect" 0
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv4 TCP/IP parameter redirects and source routing disabled." -ForegroundColor Green

Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv6 TCP/IP parameter source routing disabled." -ForegroundColor Green

# 5. Prevent Network Connection Sharing and Dual-Homing Bridging
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_ShowSharedAccessUI" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_AllowNetBridge_NLA" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_StdDomainUserSetLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fMinimizeConnections" 3
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fBlockNonDomain" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config" "AutoConnectAllowedOEM" 0
Write-Host "[+] Network connections, sharing, bridging, elevation, and hotspot settings configured." -ForegroundColor Green

# 6. Printing Spooler Web Downloads and HTTP printing block
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableWebPnPDownload" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Write-Host "[+] Printing spooler HTTP and Web service options disabled." -ForegroundColor Green

# 7. Restrict anonymous access to SAM and Named Pipes/Shares
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" "RestrictNullSessAccess" 1
Write-Host "[+] Anonymous null session share access restricted." -ForegroundColor Green

# 8. Disable WPAD
Write-Host "[+] Disabling WinHTTP Auto-Proxy service..." -ForegroundColor Gray
Set-Service -Name "WinHttpAutoProxySvc" -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name "WinHttpAutoProxySvc" -Force -ErrorAction SilentlyContinue

$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
if (-not (Test-Path $WpadPath)) {
    New-Item -Path $WpadPath -Force | Out-Null
}
Set-ItemProperty -Path $WpadPath -Name "WpadOverride" -Value 1 -Type DWord -Force
Write-Host "[+] WPAD auto-detection disabled in user preferences registry." -ForegroundColor Green

# 9. Restrict Net Session Enumeration (NetCease SDDL)
Write-Host "[+] Restricting Net Session Enumeration..." -ForegroundColor Gray
try {
    $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)")
    $BinaryForm = New-Object byte[] $SD.BinaryLength
    $SD.GetBinaryForm($BinaryForm, 0)
    $LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
    if (-not (Test-Path $LanmanSecPath)) {
        New-Item -Path $LanmanSecPath -Force | Out-Null
    }
    Set-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -Value $BinaryForm -Type Binary -Force
    Write-Host "[+] Net Session Enumeration restricted to Admins/Operators/Power Users." -ForegroundColor Green
} catch {
    Write-Error "    Failed to apply Net Session Enumeration restrictions: $($_.Exception.Message)"
}

Write-Host "Network and name resolution hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7019" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-020" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-020] Configure User Account Control Policies for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-uac-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>User Account Control (UAC) is a fundamental defense mechanism in Windows. It limits the privilege levels of running applications, executing administrative actions with standard user tokens unless elevated privileges are explicitly approved.</xhtml:p>
        <xhtml:p>Hardening UAC settings ensures: 1. <xhtml:strong>Secure Desktop Enforcement</xhtml:strong>: The elevation prompt is displayed on a separate, secure desktop environment that isolated system threads run on. This prevents third-party malware running in user space from intercepting credentials or programmatically clicking "Yes" to elevate itself. 2. <xhtml:strong>Auto-Denial of Standard User Elevation</xhtml:strong>: Standard users should not be allowed to request elevation. If a standard user triggers a task requiring administrative rights, the prompt should auto-deny rather than requesting an administrator password, preventing users from attempting to bypass controls or exposing local admin passwords on a non-secure user terminal. 3. <xhtml:strong>Admin Approval Mode</xhtml:strong>: Forcing built-in administrators to run in Admin Approval Mode ensures that even administrative users do not run web browsers or document editors with administrative tokens by default. 4. <xhtml:strong>Sudo Command Control</xhtml:strong>: The <xhtml:code>sudo</xhtml:code> command introduced in Windows 11 (24H2) allows users to run elevated commands from an unelevated console. Leaving this feature unconfigured or allowing execution within the current console session can expose elevated processes to command injection or token interception in the same console session. Restricting <xhtml:code>sudo</xhtml:code> to opening a new elevated window (<xhtml:code>1</xhtml:code>) or disabling it entirely (<xhtml:code>0</xhtml:code>) mitigates session hijacking risks. 5. <xhtml:strong>Network UAC Restrictions (`LocalAccountTokenFilterPolicy`)</xhtml:strong>: Restricting the elevation of local accounts during network logons prevents lateral movement. When set to <xhtml:code>0</xhtml:code>, local accounts (except for the built-in Administrator RID 500 account) connecting remotely via network shares or administrative interfaces cannot obtain administrative tokens, neutralizing pass-the-hash attacks using secondary local administrative accounts. 6. <xhtml:strong>Installer Detection (`EnableInstallDetection`)</xhtml:strong>: Detecting installer program behavior prevents silent software execution. When enabled, any execution of an install file or setup program by standard users or administrators triggers a UAC elevation prompt, preventing unauthorized silent program deployments. 7. <xhtml:strong>UAC Virtualization (`EnableVirtualization`)</xhtml:strong>: Virtualizing writes redirection keeps the operating system directory space clean. It redirects legacy application registry and file writes targeting system folders (like <xhtml:code>Program Files</xhtml:code> or <xhtml:code>System32</xhtml:code>) to user-profile-specific folders, allowing legacy applications to run without requiring administrative rights.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode` -&gt; </xhtml:em>
            <xhtml:em>Prompt for credentials on the secure desktop</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Behavior of the elevation prompt for standard users` -&gt; </xhtml:em>
            <xhtml:em>Automatically deny elevation requests</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Run all administrators in Admin Approval Mode` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Switch to the secure desktop when prompting for elevation` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Detect application installations and prompt for elevation` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Virtualize file and registry write failures to per-user locations` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Since the UAC network restrictions policy is not directly exposed in standard GPO security templates, deploy the registry setting via GPO Preferences:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Create a new Registry Item:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LocalAccountTokenFilterPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Configure the behavior of the sudo command` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with options set to </xhtml:em>
            <xhtml:em>Force a new elevated window</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure maximum security parameters for UAC in the system registry.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawUACPolicies.ps1">Download Script: Configure-PawUACPolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawUACPolicies.ps1
# Description: Enforces hardened User Account Control (UAC) registry configuration values including network restrictions, installer detection, and virtualization on PAWs.

Write-Host "--- Hardening User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

# ConsentPromptBehaviorAdmin = 1 (Prompt for credentials on secure desktop)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorAdmin" -Value 1 -Type DWord -Force
# ConsentPromptBehaviorUser = 0 (Automatically deny elevation requests)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorUser" -Value 0 -Type DWord -Force
# EnableLUA = 1 (Enable User Account Control / Admin Approval Mode)
Set-ItemProperty -Path $SystemPath -Name "EnableLUA" -Value 1 -Type DWord -Force
# PromptOnSecureDesktop = 1 (Switch to secure desktop when prompting)
Set-ItemProperty -Path $SystemPath -Name "PromptOnSecureDesktop" -Value 1 -Type DWord -Force
# LocalAccountTokenFilterPolicy = 0 (Apply UAC restrictions to local accounts on network logons)
Set-ItemProperty -Path $SystemPath -Name "LocalAccountTokenFilterPolicy" -Value 0 -Type DWord -Force
# EnableInstallDetection = 1 (Detect application installations and prompt for elevation)
Set-ItemProperty -Path $SystemPath -Name "EnableInstallDetection" -Value 1 -Type DWord -Force
# EnableVirtualization = 1 (Virtualize file and registry write failures to per-user locations)
Set-ItemProperty -Path $SystemPath -Name "EnableVirtualization" -Value 1 -Type DWord -Force

# Configure Windows Sudo command behavior (Enabled = 1 [Force new elevated window])
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (-not (Test-Path $SudoPath)) {
    New-Item -Path $SudoPath -Force | Out-Null
}
Set-ItemProperty -Path $SudoPath -Name "Enabled" -Value 1 -Type DWord -Force

Write-Host "[+] UAC registry values configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit UAC configurations on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawUACPolicies.ps1">Download Script: Test-PawUACPolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawUACPolicies.ps1
# Description: Verifies local system registry settings for User Account Control on PAWs.

Write-Host "--- Auditing User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$script:Vulnerable = $false

function Test-UACRegistryValue ($name, $expected, $message) {
    $val = Get-ItemProperty -Path $SystemPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { $null }
    $color = "Red"
    if ($actual -eq $expected) {
        $color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expected') | $message" -ForegroundColor $color
}

Test-UACRegistryValue "ConsentPromptBehaviorAdmin" 1 "Behavior of elevation prompt for administrators"
Test-UACRegistryValue "ConsentPromptBehaviorUser" 0 "Behavior of elevation prompt for standard users"
Test-UACRegistryValue "EnableLUA" 1 "Run all administrators in Admin Approval Mode"
Test-UACRegistryValue "PromptOnSecureDesktop" 1 "Switch to secure desktop when prompting"
Test-UACRegistryValue "LocalAccountTokenFilterPolicy" 0 "UAC network restrictions"
Test-UACRegistryValue "EnableInstallDetection" 1 "Installer detection"
Test-UACRegistryValue "EnableVirtualization" 1 "UAC virtualization"

# Audit Sudo command
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (Test-Path $SudoPath) {
    $SudoState = Get-ItemProperty -Path $SudoPath -Name "Enabled" -ErrorAction SilentlyContinue
    $SudoVal = if ($SudoState) { $SudoState.Enabled } else { 0 }
    $SudoColor = if ($SudoVal -eq 0 -or $SudoVal -eq 1) { "Green" } else { "Red" }
    Write-Host "    - Sudo Command Enabled state: $SudoVal (Required = 1 [New Window] or 0 [Disabled])" -ForegroundColor $SudoColor
    if ($SudoVal -ne 0 -and $SudoVal -ne 1) {
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - Sudo Command Enabled state: Not Configured (Default/Compliant as it inherits disabled)" -ForegroundColor Green
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUACPolicies.ps1
# Description: Enforces hardened User Account Control (UAC) registry configuration values including network restrictions, installer detection, and virtualization on PAWs.

Write-Host "--- Hardening User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

# ConsentPromptBehaviorAdmin = 1 (Prompt for credentials on secure desktop)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorAdmin" -Value 1 -Type DWord -Force
# ConsentPromptBehaviorUser = 0 (Automatically deny elevation requests)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorUser" -Value 0 -Type DWord -Force
# EnableLUA = 1 (Enable User Account Control / Admin Approval Mode)
Set-ItemProperty -Path $SystemPath -Name "EnableLUA" -Value 1 -Type DWord -Force
# PromptOnSecureDesktop = 1 (Switch to secure desktop when prompting)
Set-ItemProperty -Path $SystemPath -Name "PromptOnSecureDesktop" -Value 1 -Type DWord -Force
# LocalAccountTokenFilterPolicy = 0 (Apply UAC restrictions to local accounts on network logons)
Set-ItemProperty -Path $SystemPath -Name "LocalAccountTokenFilterPolicy" -Value 0 -Type DWord -Force
# EnableInstallDetection = 1 (Detect application installations and prompt for elevation)
Set-ItemProperty -Path $SystemPath -Name "EnableInstallDetection" -Value 1 -Type DWord -Force
# EnableVirtualization = 1 (Virtualize file and registry write failures to per-user locations)
Set-ItemProperty -Path $SystemPath -Name "EnableVirtualization" -Value 1 -Type DWord -Force

# Configure Windows Sudo command behavior (Enabled = 1 [Force new elevated window])
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (-not (Test-Path $SudoPath)) {
    New-Item -Path $SudoPath -Force | Out-Null
}
Set-ItemProperty -Path $SudoPath -Name "Enabled" -Value 1 -Type DWord -Force

Write-Host "[+] UAC registry values configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7020" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-021" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-021] Disable AutoPlay and AutoRun for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/disable-autoplay-autorun.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The AutoPlay and AutoRun features in Windows are designed to automatically execute programs or open media when a removable drive, network share, or CD-ROM is inserted or connected.</xhtml:p>
        <xhtml:p>Attackers exploit these features by placing malicious scripts, payloads, or executables on USB drives or external storage media. If AutoPlay is enabled, connecting the drive triggers automatic execution of these scripts or programs without user interaction or approval, allowing malware to achieve immediate execution in the context of the logged-on user. Disabling AutoPlay across all drive types completely mitigates this physical transmission vector.</xhtml:p>
        <xhtml:p>Additionally, non-volume devices (such as mobile phones, cameras, or media players) can still trigger AutoPlay behavior. Disallowing AutoPlay for non-volume devices ensures these devices do not introduce unauthorized execution pathways when plugged into standard client machines.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\AutoPlay Policies</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn off AutoPlay</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Options</xhtml:em>*: <xhtml:code>All drives</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Set the default behavior for AutoRun</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Options</xhtml:em>*: <xhtml:code>Do not execute any autorun commands</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Disallow Autoplay for non-volume devices</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure Explorer registry keys to disable AutoPlay, AutoRun, and AutoPlay for non-volume devices.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-PawAutoPlay.ps1">Download Script: Disable-PawAutoPlay.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-PawAutoPlay.ps1
# Description: Disables AutoPlay/AutoRun registry settings globally on all drive types and non-volume devices on PAWs.

Write-Host "--- Disabling AutoPlay and AutoRun ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"

if (-not (Test-Path $ExplorerPath)) {
    New-Item -Path $ExplorerPath -Force | Out-Null
}

# NoDriveTypeAutoRun = 0xFF (255 in decimal) disables AutoRun on all types of drives
Set-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord -Force

# NoAutorun = 1 disables AutoRun commands in inf files
Set-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -Value 1 -Type DWord -Force

# Disallow Autoplay for non-volume devices (NoAutoplayfornonVolume = 1)
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
if (-not (Test-Path $PolExplorerPath)) {
    New-Item -Path $PolExplorerPath -Force | Out-Null
}
Set-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -Value 1 -Type DWord -Force

Write-Host "[+] AutoPlay and AutoRun registry parameters set." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit AutoPlay configurations on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawAutoPlay.ps1">Download Script: Test-PawAutoPlay.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawAutoPlay.ps1
# Description: Audits local system registry parameters for AutoPlay status on PAWs.

Write-Host "--- Auditing AutoPlay Configuration ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"

$NoDriveAuto = Get-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -ErrorAction SilentlyContinue
$NoAutoCmd = Get-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -ErrorAction SilentlyContinue
$NoNonVol = Get-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -ErrorAction SilentlyContinue

$NoDriveVal = if ($NoDriveAuto) { $NoDriveAuto.NoDriveTypeAutoRun } else { 0 }
$NoAutoVal = if ($NoAutoCmd) { $NoAutoCmd.NoAutorun } else { 0 }
$NoNonVolVal = if ($NoNonVol) { $NoNonVol.NoAutoplayfornonVolume } else { 0 }

$NoDriveColor = if ($NoDriveVal -eq 255) { "Green" } else { "Red" }
$NoAutoColor = if ($NoAutoVal -eq 1) { "Green" } else { "Red" }
$NoNonVolColor = if ($NoNonVolVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - NoDriveTypeAutoRun: $NoDriveVal (Required = 255 to disable all drives)" -ForegroundColor $NoDriveColor
Write-Host "    - NoAutorun: $NoAutoVal (Required = 1)" -ForegroundColor $NoAutoColor
Write-Host "    - NoAutoplayfornonVolume: $NoNonVolVal (Required = 1)" -ForegroundColor $NoNonVolColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-PawAutoPlay.ps1
# Description: Disables AutoPlay/AutoRun registry settings globally on all drive types and non-volume devices on PAWs.

Write-Host "--- Disabling AutoPlay and AutoRun ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"

if (-not (Test-Path $ExplorerPath)) {
    New-Item -Path $ExplorerPath -Force | Out-Null
}

# NoDriveTypeAutoRun = 0xFF (255 in decimal) disables AutoRun on all types of drives
Set-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord -Force

# NoAutorun = 1 disables AutoRun commands in inf files
Set-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -Value 1 -Type DWord -Force

# Disallow Autoplay for non-volume devices (NoAutoplayfornonVolume = 1)
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
if (-not (Test-Path $PolExplorerPath)) {
    New-Item -Path $PolExplorerPath -Force | Out-Null
}
Set-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -Value 1 -Type DWord -Force

Write-Host "[+] AutoPlay and AutoRun registry parameters set." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7021" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-022" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-022] Disable Incoming Remote Desktop Access for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/restrict-rdp-access.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Remote Desktop Protocol (RDP) is one of the primary mechanisms used by attackers for lateral movement and administrative session hijacking.</xhtml:p>
        <xhtml:p>For Privileged Access Workstations (PAWs), which manage Tier 0 administrative assets: 1. <xhtml:strong>Lateral Movement Prevention</xhtml:strong>: PAWs represent physical console endpoints used to administer the forest. They must never accept inbound network connections. Disabling incoming RDP connections prevents attackers from pivoting from compromised general workstations to the PAW. 2. <xhtml:strong>Session Security</xhtml:strong>: Eliminating RDP listener ports prevents credential sniffing, password spraying, and remote exploitation of remote desktop services vulnerabilities on the administrative root of trust. 3. <xhtml:strong>Remote Assistance Block</xhtml:strong>: Disabling solicited remote assistance prevents potential remote command execution or remote support hijacking.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Disable Inbound Remote Desktop Connections</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Allow users to connect remotely by using Remote Desktop Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Disable Solicited Remote Assistance</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Remote Assistance</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure Solicited Remote Assistance</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to disable Remote Desktop and Remote Assistance, and enforce NLA and secure registry keys.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-PawRemoteDesktop.ps1">Download Script: Disable-PawRemoteDesktop.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-PawRemoteDesktop.ps1
# Description: Disables Remote Desktop and Solicited Remote Assistance connections, sets NLA requirements, and cleans parameters on PAWs.

Write-Host "--- Restricting Remote Desktop and Remote Assistance Access ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"

# 1. Disable RDP Connections (fDenyTSConnections = 1)
Set-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -Value 1 -Type DWord -Force
Write-Host "[+] Inbound Remote Desktop connections disabled." -ForegroundColor Green

# 2. Enforce Network Level Authentication (UserAuthentication = 1)
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
if (Test-Path $RdpSecPath) {
    Set-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -Value 1 -Type DWord -Force
    Write-Host "[+] Network Level Authentication (NLA) enforced." -ForegroundColor Green
}

# 3. Disable Remote Assistance (fAllowToGetHelp = 0)
Set-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force

# 4. Disable and clean Solicited Remote Assistance Policies, set SSL, and delete temp folders
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $TSPoliciesPath)) {
    New-Item -Path $TSPoliciesPath -Force | Out-Null
}
Set-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -Value 1 -Type DWord -Force

$ParamsToDelete = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
foreach ($Param in $ParamsToDelete) {
    if (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue) {
        Remove-ItemProperty -Path $TSPoliciesPath -Name $Param -Force -ErrorAction SilentlyContinue
    }
}
Write-Host "[+] Remote Desktop policies (SSL, Temp folders, Solicited Help) configured and cleaned." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit Remote Desktop and Remote Assistance status on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawRemoteDesktopStatus.ps1">Download Script: Test-PawRemoteDesktopStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawRemoteDesktopStatus.ps1
# Description: Audits local RDP, Remote Assistance, security layer, temp folders, and NLA registry configuration and listening firewall ports on PAWs.

Write-Host "--- Auditing Remote Desktop Configuration ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"

$DenyTS = Get-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -ErrorAction SilentlyContinue
$DenyVal = if ($DenyTS) { $DenyTS.fDenyTSConnections } else { 1 }

$NlaProp = Get-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -ErrorAction SilentlyContinue
$NlaVal = if ($NlaProp) { $NlaProp.UserAuthentication } else { 0 }

$DenyColor = if ($DenyVal -eq 1) { "Green" } else { "Red" }
$NlaColor = if ($NlaVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - fDenyTSConnections: $DenyVal (Required = 1 to block all)" -ForegroundColor $DenyColor
Write-Host "    - UserAuthentication (NLA): $NlaVal (Required = 1 if RDP is enabled)" -ForegroundColor $NlaColor

# Check if port 3389 firewall rule is active and enabled
$RdpFirewall = Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -ErrorAction SilentlyContinue
if ($RdpFirewall) {
    $FirewallColor = if ($RdpFirewall.Enabled -eq $true) { "Red" } else { "Green" }
    Write-Host "    - RDP Inbound Firewall Rule Active: $($RdpFirewall.Enabled) (Expected = False)" -ForegroundColor $FirewallColor
}

# Audit Remote Assistance
$GetHelpTS = Get-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -ErrorAction SilentlyContinue
$GetHelpTSVal = if ($GetHelpTS) { $GetHelpTS.fAllowToGetHelp } else { 0 }
$HelpColor = if ($GetHelpTSVal -eq 0) { "Green" } else { "Red" }
Write-Host "    - fAllowToGetHelp (Terminal Server): $GetHelpTSVal (Recommended = 0)" -ForegroundColor $HelpColor

# Audit Solicited Remote Assistance Policy, Security Layer, and Temp Folders
if (Test-Path $TSPoliciesPath) {
    $PolGetHelp = Get-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -ErrorAction SilentlyContinue
    $PolGetHelpVal = if ($PolGetHelp) { $PolGetHelp.fAllowToGetHelp } else { $null }
    
    $PolHelpColor = if ($PolGetHelpVal -eq 0) { "Green" } else { "Red" }
    Write-Host "    - fAllowToGetHelp (Policies): $PolGetHelpVal (Recommended = 0)" -ForegroundColor $PolHelpColor
    
    $SecurityLayerProp = Get-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -ErrorAction SilentlyContinue
    $SecurityLayerVal = if ($SecurityLayerProp) { $SecurityLayerProp.SecurityLayer } else { $null }
    $SecLayerColor = if ($SecurityLayerVal -eq 2) { "Green" } else { "Red" }
    Write-Host "    - SecurityLayer (SSL): $SecurityLayerVal (Required = 2)" -ForegroundColor $SecLayerColor

    $DeleteTempProp = Get-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -ErrorAction SilentlyContinue
    $DeleteTempVal = if ($DeleteTempProp) { $DeleteTempProp.DeleteTempDirsOnExit } else { $null }
    $DeleteTempColor = if ($DeleteTempVal -eq 1) { "Green" } else { "Red" }
    Write-Host "    - DeleteTempDirsOnExit (Temp Folders): $DeleteTempVal (Required = 1)" -ForegroundColor $DeleteTempColor

    $Params = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
    foreach ($Param in $Params) {
        $Val = (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue).$Param
        if ($null -ne $Val) {
            Write-Host "    - VULNERABLE: Solicited Remote Assistance parameter '$Param' is set to '$Val' (Expected: Deleted/Not Configured)" -ForegroundColor Red
        } else {
            Write-Host "    - Parameter '$Param': Not Configured (Correct)" -ForegroundColor Green
        }
    }
} else {
    Write-Host "    - Solicited Remote Assistance Policy Path does not exist" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-PawRemoteDesktop.ps1
# Description: Disables Remote Desktop and Solicited Remote Assistance connections, sets NLA requirements, and cleans parameters on PAWs.

Write-Host "--- Restricting Remote Desktop and Remote Assistance Access ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"

# 1. Disable RDP Connections (fDenyTSConnections = 1)
Set-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -Value 1 -Type DWord -Force
Write-Host "[+] Inbound Remote Desktop connections disabled." -ForegroundColor Green

# 2. Enforce Network Level Authentication (UserAuthentication = 1)
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
if (Test-Path $RdpSecPath) {
    Set-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -Value 1 -Type DWord -Force
    Write-Host "[+] Network Level Authentication (NLA) enforced." -ForegroundColor Green
}

# 3. Disable Remote Assistance (fAllowToGetHelp = 0)
Set-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force

# 4. Disable and clean Solicited Remote Assistance Policies, set SSL, and delete temp folders
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $TSPoliciesPath)) {
    New-Item -Path $TSPoliciesPath -Force | Out-Null
}
Set-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -Value 1 -Type DWord -Force

$ParamsToDelete = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
foreach ($Param in $ParamsToDelete) {
    if (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue) {
        Remove-ItemProperty -Path $TSPoliciesPath -Name $Param -Force -ErrorAction SilentlyContinue
    }
}
Write-Host "[+] Remote Desktop policies (SSL, Temp folders, Solicited Help) configured and cleaned." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7022" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-023" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-023] WSUS Client Configuration for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/wsus-client-config.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In an isolated, air-gapped network, workstations cannot connect directly to Microsoft's online Update servers. If the system is left in its default configuration: 1. <xhtml:strong>DNS/Firewall Pollution</xhtml:strong>: Workstations will continuously attempt to resolve and connect to public Windows Update URLs (e.g., <xhtml:code>*.update.microsoft.com</xhtml:code>), filling firewall and local DNS resolver cache logs with timeouts and block events. 2. <xhtml:strong>Missing Updates</xhtml:strong>: Workstations will fail to receive security patches, critical updates, and Windows Defender definitions. 3. <xhtml:strong>Control Bypass</xhtml:strong>: Attackers or unapproved software could attempt to install out-of-band features or packages if update routes are not explicitly locked to internal sources.</xhtml:p>
        <xhtml:p>Enforcing the intranet update service location redirects all system update queries to the local WSUS server. Furthermore, enforcing Windows <xhtml:strong>Delivery Optimization</xhtml:strong> download mode to <xhtml:code>Group (2)</xhtml:code> limits peer-to-peer update sharing strictly to computers within the same active directory domain/group or local subnet boundaries, reducing bandwidth constraints on WAN/intranet segments and preventing unmanaged peer sharing.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Windows Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure Automatic Updates</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure automatic updating</xhtml:em>*: <xhtml:code>4 - Auto download and schedule the install</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the service location:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Specify intranet Microsoft update service location</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet update service for detecting updates</xhtml:em>*: <xhtml:code>http://local-wsus.domain.local:8530</xhtml:code> (Replace with your internal WSUS FQDN or IP)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet statistics server</xhtml:em>*: <xhtml:code>http://local-wsus.domain.local:8530</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Do not connect to any Windows Update Internet locations</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code> (blocks fallback to public servers)</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Delivery Optimization</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Download Mode</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Download Mode</xhtml:em>*: <xhtml:code>Group (2)</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure registry keys to enforce local WSUS parameters and Delivery Optimization download mode.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PawWSUSClientConfiguration.ps1">Download Script: Set-PawWSUSClientConfiguration.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PawWSUSClientConfiguration.ps1
# Description: Configures local registry keys to point the Windows Update client to the intranet WSUS server and enforces DO Group mode on PAWs.

Write-Host "--- Configuring WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

# 1. Create keys if they do not exist
if (-not (Test-Path $WUPath)) {
    New-Item -Path $WUPath -Force | Out-Null
}
if (-not (Test-Path $WUAUPath)) {
    New-Item -Path $WUAUPath -Force | Out-Null
}
if (-not (Test-Path $DOPath)) {
    New-Item -Path $DOPath -Force | Out-Null
}

# Define intranet WSUS URL
$WSUSServer = "http://local-wsus.domain.local:8530"

# 2. Configure update location and statistics server
Set-ItemProperty -Path $WUPath -Name "WUServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "WUStatusServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "DoNotConnectToWindowsUpdateInternetLocations" -Value 1 -Type DWord -Force

# 3. Configure Automatic Updates behavior (AUOptions = 4: Auto Download &amp; Schedule)
Set-ItemProperty -Path $WUAUPath -Name "NoAutoUpdate" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "AUOptions" -Value 4 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "UseWUServer" -Value 1 -Type DWord -Force

# 4. Enforce DODownloadMode = 2 (Group)
Set-ItemProperty -Path $DOPath -Name "DODownloadMode" -Value 2 -Type DWord -Force

Write-Host "[+] Local WSUS parameters and Delivery Optimization download mode applied." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the WSUS client configuration status on the PAW:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawWSUSClientStatus.ps1">Download Script: Test-PawWSUSClientStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawWSUSClientStatus.ps1
# Description: Audits registry values to verify WSUS server assignment and Delivery Optimization configuration on PAWs.

Write-Host "--- Auditing WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

$WUServerProp = Get-ItemProperty -Path $WUPath -Name "WUServer" -ErrorAction SilentlyContinue
$WUStatusProp = Get-ItemProperty -Path $WUPath -Name "WUStatusServer" -ErrorAction SilentlyContinue
$UseWUServerProp = Get-ItemProperty -Path $WUAUPath -Name "UseWUServer" -ErrorAction SilentlyContinue

$WUServerVal = if ($WUServerProp) { $WUServerProp.WUServer } else { "" }
$WUStatusVal = if ($WUStatusProp) { $WUStatusProp.WUStatusServer } else { "" }
$UseWUVal = if ($UseWUServerProp) { $UseWUServerProp.UseWUServer } else { 0 }

$ServerColor = if ($WUServerVal -like "http*") { "Green" } else { "Red" }
$UseColor = if ($UseWUVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - Intranet WUServer: $WUServerVal" -ForegroundColor $ServerColor
Write-Host "    - Intranet WUStatusServer: $WUStatusVal" -ForegroundColor $ServerColor
Write-Host "    - UseWUServer Active: $UseWUVal (Required = 1)" -ForegroundColor $UseColor

# Audit Delivery Optimization
$DOVal = if (Test-Path $DOPath) { (Get-ItemProperty -Path $DOPath -Name "DODownloadMode" -ErrorAction SilentlyContinue).DODownloadMode } else { $null }
$DOColor = if ($DOVal -eq 2) { "Green" } else { "Red" }
Write-Host "    - Delivery Optimization DODownloadMode: $DOVal (Expected = 2)" -ForegroundColor $DOColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PawWSUSClientConfiguration.ps1
# Description: Configures local registry keys to point the Windows Update client to the intranet WSUS server and enforces DO Group mode on PAWs.

Write-Host "--- Configuring WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

# 1. Create keys if they do not exist
if (-not (Test-Path $WUPath)) {
    New-Item -Path $WUPath -Force | Out-Null
}
if (-not (Test-Path $WUAUPath)) {
    New-Item -Path $WUAUPath -Force | Out-Null
}
if (-not (Test-Path $DOPath)) {
    New-Item -Path $DOPath -Force | Out-Null
}

# Define intranet WSUS URL
$WSUSServer = "http://local-wsus.domain.local:8530"

# 2. Configure update location and statistics server
Set-ItemProperty -Path $WUPath -Name "WUServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "WUStatusServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "DoNotConnectToWindowsUpdateInternetLocations" -Value 1 -Type DWord -Force

# 3. Configure Automatic Updates behavior (AUOptions = 4: Auto Download &amp; Schedule)
Set-ItemProperty -Path $WUAUPath -Name "NoAutoUpdate" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "AUOptions" -Value 4 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "UseWUServer" -Value 1 -Type DWord -Force

# 4. Enforce DODownloadMode = 2 (Group)
Set-ItemProperty -Path $DOPath -Name "DODownloadMode" -Value 2 -Type DWord -Force

Write-Host "[+] Local WSUS parameters and Delivery Optimization download mode applied." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7023" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-025" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-025] Configure Exploit Protection Profile for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-exploit-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Exploit Protection provides a set of advanced memory and vulnerability mitigations. These mitigations protect both the operating system and applications from memory corruption, buffer overflows, execution redirection, and process hijack attempts.</xhtml:p>
        <xhtml:p>By enforcing system-wide mitigations: 1. <xhtml:strong>Data Execution Prevention (DEP)</xhtml:strong>: Enforces non-executable memory pages, preventing attackers from executing shellcode injected into data-only memory regions (such as the stack or heap). 2. <xhtml:strong>Address Space Layout Randomization (ASLR)</xhtml:strong>: Randomizes the locations where system components, executable code, and memory allocations are loaded. Enabling Mandatory ASLR (Force Relocate Images), Bottom-Up ASLR, and High Entropy ASLR makes memory structures unpredictable, thwarting return-oriented programming (ROP) exploits. 3. <xhtml:strong>Control Flow Guard (CFG)</xhtml:strong>: Verifies control flow integrity for indirect call targets at compile time, preventing attackers from hijacking indirect jumps to point to arbitrary payloads. 4. <xhtml:strong>Structured Exception Handler Overwrite Protection (SEHOP)</xhtml:strong>: Blocks exploits that overwrite Structured Exception Handlers (SEH) to gain control of execution paths during error handling. 5. <xhtml:strong>Heap Termination on Corruption</xhtml:strong>: Immediately terminates a process if corruption is detected in its heap. This blocks heap-based buffer overflow exploitation before execution control can be seized.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Generate the Reference XML Configuration File</xhtml:h4>
        <xhtml:p>Before configuring the GPO, you must create a reference XML file containing the desired Exploit Protection mitigations: 1. On a reference workstation, open the <xhtml:strong>Windows Security</xhtml:strong> app. 2. Select <xhtml:strong>App &amp; browser control</xhtml:strong> and click <xhtml:strong>Exploit protection settings</xhtml:strong>. 3. Under the <xhtml:strong>System settings</xhtml:strong> tab, configure the following: <xhtml:em> </xhtml:em>
          <xhtml:em>Control Flow Guard (CFG)</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Data Execution Prevention (DEP)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>Force randomization for images (Mandatory ASLR)</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Randomize memory allocations (Bottom-up ASLR)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>High-entropy ASLR</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Validate exception chains (SEHOP)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>Validate heap integrity</xhtml:em>
          <xhtml:em>: On by default 4. Select the </xhtml:em>
          <xhtml:em>Program settings</xhtml:em>
          <xhtml:em> tab and configure application-specific overrides for administrative utilities and scripting hosts (`powershell.exe`, `cmd.exe`, etc.) to apply EAF, IAF, and ROP mitigations. 5. Scroll to the bottom of the page and click </xhtml:em>
          <xhtml:em>Export settings</xhtml:em>*. 6. Save the file as <xhtml:code>ExploitProtectionSettings.xml</xhtml:code>. 7. Copy this XML file to a location accessible by target endpoints, or distribute it to local target directories (e.g., <xhtml:code>C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml</xhtml:code>) via Group Policy Preferences (Files).</xhtml:p>
        <xhtml:h4>Step 2: Configure the Group Policy Setting</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Windows Defender Exploit Guard\Exploit Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Use a common set of exploit protection settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>
            <xhtml:em>: Under the </xhtml:em>Path<xhtml:em> or </xhtml:em>Url* field, enter the full path to the XML file (e.g., <xhtml:code>C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml</xhtml:code> or a UNC share path).</xhtml:li>
          <xhtml:li>If utilizing Microsoft Security Guide templates:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\MS Security Guide</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Configure policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Enable Certificate Padding` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Enable Structured Exception Handling Overwrite Protection (SEHOP)` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Lock down Exploit Protection settings against user tampering:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Defender Security Center\App and Browser protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Configure policy: </xhtml:em>
            <xhtml:em>Prevent users from modifying settings</xhtml:em>
            <xhtml:em> -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target PAWs.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the exploit protection profile locally on individual systems or standalone hosts.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawExploitProtection.ps1">Download Script: Configure-PawExploitProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawExploitProtection.ps1
# Description: Generates the system-wide and application-specific Exploit Protection XML profile, applies it locally, and configures the policy registry keys on PAWs.

Write-Host "Applying Exploit Protection Profile..." -ForegroundColor Cyan

# 1. Define the XML content including System and App settings
$XmlContent = @"
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;MitigationPolicy&gt;
  &lt;SystemConfig&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;SEHOP Enable="true" TelemetryOnly="false" /&gt;
    &lt;Heap TerminateOnError="true" /&gt;
  &lt;/SystemConfig&gt;
  &lt;AppConfig Executable="wscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="cscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="powershell.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
&lt;/MitigationPolicy&gt;
"@

# 2. Create the target directory and write the XML file
$TargetDir = "C:\ProgramData\ExploitProtection"
if (-not (Test-Path $TargetDir)) {
    New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
}

$XmlPath = "$TargetDir\ExploitProtectionSettings.xml"
Set-Content -Path $XmlPath -Value $XmlContent -Encoding UTF8
Write-Host "Exploit Protection XML profile written to $($XmlPath)" -ForegroundColor Gray

# 3. Apply the settings locally using the cmdlet
if (Get-Command Set-ProcessMitigation -ErrorAction SilentlyContinue) {
    Set-ProcessMitigation -PolicyFilePath $XmlPath
    Write-Host "[+] Exploit protection system settings applied locally." -ForegroundColor Green
} else {
    Write-Warning "Set-ProcessMitigation cmdlet is not available. Please ensure you are running Windows 10/11 or Windows Server 2016+."
}

# 4. Configure policy registry keys to point to the XML file
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -Value $XmlPath -Type String -Force
Write-Host "[+] GPO policy registry values configured." -ForegroundColor Green

# 5. Configure MS Security Guide mitigations: Certificate Padding check and SEHOP registry keys
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustPath)) {
    New-Item -Path $WintrustPath -Force | Out-Null
}
Set-ItemProperty -Path $WintrustPath -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustWow64Path)) {
    New-Item -Path $WintrustWow64Path -Force | Out-Null
}
Set-ItemProperty -Path $WintrustWow64Path -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
if (-not (Test-Path $SessionKernelPath)) {
    New-Item -Path $SessionKernelPath -Force | Out-Null
}
Set-ItemProperty -Path $SessionKernelPath -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "[+] Certificate Padding check and SEHOP registry keys applied." -ForegroundColor Green

# 6. Prevent users from modifying Exploit Protection settings in Windows Security Center
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
if (-not (Test-Path $SecCenterPath)) {
    New-Item -Path $SecCenterPath -Force | Out-Null
}
Set-ItemProperty -Path $SecCenterPath -Name "DisallowExploitProtectionOverride" -Value 1 -Type DWord -Force
Write-Host "[+] Exploit protection override lockdown applied." -ForegroundColor Green

Write-Host "Exploit Protection Profile application completed successfully." -ForegroundColor Cyan</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawExploitProtectionStatus.ps1">Download Script: Get-PawExploitProtectionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawExploitProtectionStatus.ps1
# Description: Audits system-wide Exploit Protection settings against the recommended security baseline on PAWs.

Write-Host "Auditing system-wide Exploit Protection mitigations..." -ForegroundColor Cyan

$BaselineFailed = $false
$Mitigations = Get-ProcessMitigation -System

# Helper function to evaluate and display status
function Test-MitigationSetting {
    param(
        [string]$MitigationName,
        [string]$CurrentValue,
        [string]$ExpectedValue
    )
    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "  [PASS] $($MitigationName): $($CurrentValue)" -ForegroundColor Green
    } else {
        Write-Host "  [FAIL] $($MitigationName): $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:BaselineFailed = $true
    }
}

Write-Host "`nSystem-wide Mitigations:" -ForegroundColor Gray

# Audit DEP
Test-MitigationSetting -MitigationName "DEP Enable" -CurrentValue $Mitigations.DEP.Enable -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "DEP EmulateAtlThunks" -CurrentValue $Mitigations.DEP.EmulateAtlThunks -ExpectedValue "OFF"

# Audit ASLR
Test-MitigationSetting -MitigationName "ASLR ForceRelocateImages" -CurrentValue $Mitigations.ASLR.ForceRelocateImages -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR BottomUp" -CurrentValue $Mitigations.ASLR.BottomUp -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR HighEntropy" -CurrentValue $Mitigations.ASLR.HighEntropy -ExpectedValue "ON"

# Audit CFG
Test-MitigationSetting -MitigationName "CFG Enable" -CurrentValue $Mitigations.CFG.Enable -ExpectedValue "ON"

# Audit SEHOP
Test-MitigationSetting -MitigationName "SEHOP Enable" -CurrentValue $Mitigations.SEHOP.Enable -ExpectedValue "ON"

# Audit Heap
Test-MitigationSetting -MitigationName "Heap TerminateOnError" -CurrentValue $Mitigations.Heap.TerminateOnError -ExpectedValue "ON"

# Audit Registry Policy and XML Configuration
Write-Host "`nRegistry Policy and XML Configuration:" -ForegroundColor Gray
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (Test-Path $RegPath) {
    $SettingsValue = Get-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -ErrorAction SilentlyContinue
    if ($SettingsValue -and $SettingsValue.ExploitProtectionSettings -ne "") {
        $XmlPath = $SettingsValue.ExploitProtectionSettings
        Write-Host "  [PASS] Exploit Protection Policy registry key is configured." -ForegroundColor Green
        Write-Host "         Path: $XmlPath" -ForegroundColor Gray
        
        if (Test-Path $XmlPath) {
            Write-Host "  [PASS] Exploit Protection XML file exists." -ForegroundColor Green
            try {
                [xml]$xml = Get-Content -Path $XmlPath -Raw -ErrorAction Stop
                
                # Verify SystemConfig block
                if ($xml.MitigationPolicy.SystemConfig) {
                    Write-Host "  [PASS] XML contains SystemConfig block." -ForegroundColor Green
                } else {
                    Write-Host "  [FAIL] XML is missing SystemConfig block." -ForegroundColor Red
                    $BaselineFailed = $true
                }
                
                # Verify major AppConfigs
                $ExpectedApps = @("wscript.exe", "cscript.exe", "powershell.exe")
                $ConfiguredApps = $xml.MitigationPolicy.AppConfig | ForEach-Object { $_.Executable }
                
                foreach ($app in $ExpectedApps) {
                    if ($ConfiguredApps -contains $app) {
                        Write-Host "  [PASS] XML contains application profile for: $app" -ForegroundColor Green
                    } else {
                        Write-Host "  [FAIL] XML is missing application profile for: $app" -ForegroundColor Red
                        $BaselineFailed = $true
                    }
                }
            } catch {
                Write-Host "  [FAIL] Failed to parse Exploit Protection XML. Error: $($_.Exception.Message)" -ForegroundColor Red
                $BaselineFailed = $true
            }
        } else {
            Write-Host "  [FAIL] Exploit Protection XML file does not exist at specified path." -ForegroundColor Red
            $BaselineFailed = $true
        }
    } else {
        Write-Host "  [FAIL] Exploit Protection Policy registry key is empty or missing." -ForegroundColor Red
        $BaselineFailed = $true
    }
} else {
    Write-Host "  [FAIL] Exploit Protection Policy registry path does not exist." -ForegroundColor Red
    $BaselineFailed = $true
}

# Audit MS Security Guide Registry Settings
Write-Host "`nMS Security Guide Mitigations (Certificate Padding &amp; SEHOP):" -ForegroundColor Gray

function Test-MitigationRegistryValue ($path, $name, $expectedValue) {
    $val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    $color = "Red"
    if ($actual -eq $expectedValue) {
        $color = "Green"
    } else {
        $script:BaselineFailed = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expectedValue')" -ForegroundColor $color
}

$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustPath "EnableCertPaddingCheck" 1

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustWow64Path "EnableCertPaddingCheck" 1

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
Test-MitigationRegistryValue $SessionKernelPath "DisableExceptionChainValidation" 0

$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
Test-MitigationRegistryValue $SecCenterPath "DisallowExploitProtectionOverride" 1

Write-Host ""
if ($BaselineFailed) {
    Write-Host "Auditing FAILED: One or more configurations do not match the secure baseline." -ForegroundColor Red
    exit 1
} else {
    Write-Host "Auditing PASSED: All configurations match the secure baseline." -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawExploitProtection.ps1
# Description: Generates the system-wide and application-specific Exploit Protection XML profile, applies it locally, and configures the policy registry keys on PAWs.

Write-Host "Applying Exploit Protection Profile..." -ForegroundColor Cyan

# 1. Define the XML content including System and App settings
$XmlContent = @"
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;MitigationPolicy&gt;
  &lt;SystemConfig&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;SEHOP Enable="true" TelemetryOnly="false" /&gt;
    &lt;Heap TerminateOnError="true" /&gt;
  &lt;/SystemConfig&gt;
  &lt;AppConfig Executable="wscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="cscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="powershell.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
&lt;/MitigationPolicy&gt;
"@

# 2. Create the target directory and write the XML file
$TargetDir = "C:\ProgramData\ExploitProtection"
if (-not (Test-Path $TargetDir)) {
    New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
}

$XmlPath = "$TargetDir\ExploitProtectionSettings.xml"
Set-Content -Path $XmlPath -Value $XmlContent -Encoding UTF8
Write-Host "Exploit Protection XML profile written to $($XmlPath)" -ForegroundColor Gray

# 3. Apply the settings locally using the cmdlet
if (Get-Command Set-ProcessMitigation -ErrorAction SilentlyContinue) {
    Set-ProcessMitigation -PolicyFilePath $XmlPath
    Write-Host "[+] Exploit protection system settings applied locally." -ForegroundColor Green
} else {
    Write-Warning "Set-ProcessMitigation cmdlet is not available. Please ensure you are running Windows 10/11 or Windows Server 2016+."
}

# 4. Configure policy registry keys to point to the XML file
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -Value $XmlPath -Type String -Force
Write-Host "[+] GPO policy registry values configured." -ForegroundColor Green

# 5. Configure MS Security Guide mitigations: Certificate Padding check and SEHOP registry keys
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustPath)) {
    New-Item -Path $WintrustPath -Force | Out-Null
}
Set-ItemProperty -Path $WintrustPath -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustWow64Path)) {
    New-Item -Path $WintrustWow64Path -Force | Out-Null
}
Set-ItemProperty -Path $WintrustWow64Path -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
if (-not (Test-Path $SessionKernelPath)) {
    New-Item -Path $SessionKernelPath -Force | Out-Null
}
Set-ItemProperty -Path $SessionKernelPath -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "[+] Certificate Padding check and SEHOP registry keys applied." -ForegroundColor Green

# 6. Prevent users from modifying Exploit Protection settings in Windows Security Center
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
if (-not (Test-Path $SecCenterPath)) {
    New-Item -Path $SecCenterPath -Force | Out-Null
}
Set-ItemProperty -Path $SecCenterPath -Name "DisallowExploitProtectionOverride" -Value 1 -Type DWord -Force
Write-Host "[+] Exploit protection override lockdown applied." -ForegroundColor Green

Write-Host "Exploit Protection Profile application completed successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7025" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-026" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-026] Restrict Safe Mode Access to Administrators on PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/disable-safe-mode-for-standard-users.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Malicious actors with standard user credentials can potentially bypass local security policies, local endpoint detection and response (EDR) agents, and group policy restrictions by booting the system into Safe Mode. In Safe Mode, many security agents and services do not load, creating an environment where local controls can be circumvented.</xhtml:p>
        <xhtml:p>By configuring <xhtml:code>SafeModeBlockNonAdmins = 1</xhtml:code>: 1. <xhtml:strong>Prevent Credential Bypass</xhtml:strong>: Standard users are blocked from logging in during Safe Mode, ensuring they cannot exploit the disabled security agents to execute unauthorized programs or extract system information. 2. <xhtml:strong>Maintenance Integrity</xhtml:strong>: Safe Mode remains accessible exclusively to system administrators for debugging and recovery, ensuring administrative capability is preserved while mitigating standard user risk.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Because there is no native Administrative Template (ADMX) policy for this setting, it must be deployed using Group Policy Preferences (GPP) to configure the registry directly.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click in the right pane, select <xhtml:strong>New</xhtml:strong> &gt; <xhtml:strong>Registry Item</xhtml:strong>, and configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SafeModeBlockNonAdmins</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone systems or during reference image build phases.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawDisableSafeModeNonAdmins.ps1">Download Script: Configure-PawDisableSafeModeNonAdmins.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawDisableSafeModeNonAdmins.ps1
# Description: Prevents standard users from logging into the system while in Safe Mode by setting SafeModeBlockNonAdmins to 1 on PAWs.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"
$ValueData = 1

Write-Host "Applying hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawSafeModeNonAdminsStatus.ps1">Download Script: Get-PawSafeModeNonAdminsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawSafeModeNonAdminsStatus.ps1
# Description: Checks the current configuration state of SafeModeBlockNonAdmins registry setting on PAWs.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"

Write-Host "Auditing hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (Test-Path $RegPath) {
    $value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $value -and $value.$ValueName -eq 1) {
        Write-Host "Audit Result: Compliant. Standard users are blocked from logging in during Safe Mode ($ValueName = 1)." -ForegroundColor Green
        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. Standard users are allowed to log in during Safe Mode." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDisableSafeModeNonAdmins.ps1
# Description: Prevents standard users from logging into the system while in Safe Mode by setting SafeModeBlockNonAdmins to 1 on PAWs.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"
$ValueData = 1

Write-Host "Applying hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7026" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-027" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-027] Configure Windows Defender Firewall and Block LOLBins for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-windows-firewall.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Defender Firewall is the primary host-based security control protecting endpoints from unauthorized incoming network connections and regulating outgoing network behaviors. A secure baseline requires enabling the firewall on all profiles, setting inbound connections to block by default, disabling notification prompts that can be bypassed by users, and implementing detailed auditing/logging to monitor network anomalies.</xhtml:p>
        <xhtml:p>Additionally: 1. <xhtml:strong>Outbound LOLBins Blocking</xhtml:strong>: Malicious actors frequently abuse built-in Windows administrative utilities (known as Living Off the Land Binaries, or LOLBins) to download malicious payloads, exfiltrate sensitive data, and communicate with external command-and-control (C2) servers. Blocking outbound network communication for binaries that have no legitimate business requirement to connect to external networks (such as <xhtml:code>mshta.exe</xhtml:code>, <xhtml:code>certutil.exe</xhtml:code>, <xhtml:code>bitsadmin.exe</xhtml:code>, <xhtml:code>regsvr32.exe</xhtml:code>, <xhtml:code>rundll32.exe</xhtml:code>, <xhtml:code>cscript.exe</xhtml:code>, <xhtml:code>wscript.exe</xhtml:code>, and <xhtml:code>hh.exe</xhtml:code>) significantly mitigates these threat vectors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure Profile States and Logging</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management workstation.</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Windows Defender Firewall with Advanced Security</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Domain Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\domainfw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Private Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\privatefw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Public Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\publicfw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Create Outbound Rules for Known LOLBins</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security\Outbound Rules</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new rule for each target LOLBin binary (e.g., mshta.exe, certutil.exe, bitsadmin.exe, regsvr32.exe, rundll32.exe, cscript.exe, wscript.exe, hh.exe, calc.exe, notepad.exe, conhost.exe, RunScriptHelper.exe):</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>Outbound Rules</xhtml:em>
            <xhtml:em> and select </xhtml:em>
            <xhtml:em>New Rule...</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Program</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Program</xhtml:em>*: Choose <xhtml:code>This program path</xhtml:code> and enter the path matching the binary (both x64 and x86 paths if applicable, e.g., <xhtml:code>%SystemRoot%\System32\mshta.exe</xhtml:code> and <xhtml:code>%SystemRoot%\SysWOW64\mshta.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: Select <xhtml:code>Domain</xhtml:code>, <xhtml:code>Private</xhtml:code>, and <xhtml:code>Public</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: Specify a descriptive name (e.g., <xhtml:code>Hardening: Block Outbound mshta.exe (x64)</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure Windows Defender Firewall profiles, logging parameters, merge settings, and outbound LOLBins rules.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawWindowsFirewall.ps1">Download Script: Configure-PawWindowsFirewall.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawWindowsFirewall.ps1
# Description: Configures Windows Defender Firewall profiles (Domain, Private, Public) and blocks outbound traffic for known LOLBins on PAWs.

Write-Host "Configuring Windows Defender Firewall profiles..." -ForegroundColor Cyan

# 1. Configure profiles
$FWProfiles = @("Domain", "Private", "Public")
foreach ($FWProfile in $FWProfiles) {
    $LogFile = "$env:windir\System32\logfiles\firewall\$($FWProfile.ToLower())fw.log"
    
    Set-NetFirewallProfile -Profile $FWProfile `
        -Enabled True `
        -DefaultInboundAction Block `
        -DefaultOutboundAction Allow `
        -NotifyOnListen False `
        -AllowLocalPolicyMerge False `
        -AllowLocalIPsecPolicyMerge False `
        -LogFileName $LogFile `
        -LogMaxSizeKilobytes 16384 `
        -LogBlocked True `
        -LogAllowed False | Out-Null
    Write-Host "[+] Profile '$FWProfile' configured with logging and defaults." -ForegroundColor Green
}

# 2. Block outbound traffic for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Configuring outbound firewall block rules for known LOLBins..." -ForegroundColor Cyan

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Existing = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -DisplayName $DisplayName `
            -Name $DisplayName `
            -Direction Outbound `
            -Action Block `
            -Program $Bin.Path `
            -Profile Any `
            -Enabled True | Out-Null
        Write-Host "[+] Outbound block rule created for $($Bin.Name)." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -DisplayName $DisplayName -Action Block -Enabled True | Out-Null
        Write-Host "[~] Outbound block rule for $($Bin.Name) already exists, updated state to Enabled/Block." -ForegroundColor Gray
    }
}

Write-Host "Firewall profiles and LOLBins outbound rules configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawWindowsFirewallStatus.ps1">Download Script: Get-PawWindowsFirewallStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawWindowsFirewallStatus.ps1
# Description: Audits Windows Defender Firewall profile configurations and outbound block rules for known LOLBins on PAWs.

Write-Host "--- Auditing Windows Defender Firewall Configuration ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to audit firewall profiles
function Test-FirewallProfile ($ProfileName, $ExpectMergeLocal, $ExpectMergeIPsec) {
    $FWProfile = Get-NetFirewallProfile -Profile $ProfileName -ErrorAction SilentlyContinue
    if ($null -eq $FWProfile) {
        Write-Host "    - Profile '$ProfileName' NOT FOUND" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    
    $EnabledColor = if ($FWProfile.Enabled -eq $true) { "Green" } else { "Red" }
    $InboundColor = if ($FWProfile.DefaultInboundAction -eq "Block") { "Green" } else { "Red" }
    $OutboundColor = if ($FWProfile.DefaultOutboundAction -eq "Allow") { "Green" } else { "Red" }
    $NotifyColor = if ($FWProfile.NotifyOnListen -eq $false) { "Green" } else { "Red" }
    
    Write-Host "  * Profile: $ProfileName" -ForegroundColor Gray
    Write-Host "    - Enabled: $($FWProfile.Enabled) (Expected: True)" -ForegroundColor $EnabledColor
    Write-Host "    - DefaultInboundAction: $($FWProfile.DefaultInboundAction) (Expected: Block)" -ForegroundColor $InboundColor
    Write-Host "    - DefaultOutboundAction: $($FWProfile.DefaultOutboundAction) (Expected: Allow)" -ForegroundColor $OutboundColor
    Write-Host "    - NotifyOnListen: $($FWProfile.NotifyOnListen) (Expected: False)" -ForegroundColor $NotifyColor
    
    # Check log configurations
    $LogPath = "$env:windir\System32\logfiles\firewall\$($ProfileName.ToLower())fw.log"
    $LogPathColor = if ($FWProfile.LogFileName -eq $LogPath) { "Green" } else { "Red" }
    $LogSizeColor = if ($FWProfile.LogMaxSizeKilobytes -ge 16384) { "Green" } else { "Red" }
    $LogBlockedColor = if ($FWProfile.LogBlocked -eq $true) { "Green" } else { "Red" }
    $LogAllowedColor = if ($FWProfile.LogAllowed -eq $false) { "Green" } else { "Red" }
    
    Write-Host "    - LogFileName: $($FWProfile.LogFileName) (Expected: $LogPath)" -ForegroundColor $LogPathColor
    Write-Host "    - LogMaxSizeKilobytes: $($FWProfile.LogMaxSizeKilobytes) (Expected: &gt;= 16384)" -ForegroundColor $LogSizeColor
    Write-Host "    - LogBlocked: $($FWProfile.LogBlocked) (Expected: True)" -ForegroundColor $LogBlockedColor
    Write-Host "    - LogAllowed: $($FWProfile.LogAllowed) (Expected: False)" -ForegroundColor $LogAllowedColor
    
    if ($FWProfile.Enabled -ne $true -or $FWProfile.DefaultInboundAction -ne "Block" -or $FWProfile.NotifyOnListen -ne $false -or $FWProfile.LogFileName -ne $LogPath -or $FWProfile.LogMaxSizeKilobytes -lt 16384 -or $FWProfile.LogBlocked -ne $true -or $FWProfile.LogAllowed -ne $false) {
        $script:Vulnerable = $true
    }
    
    if ($null -ne $ExpectMergeLocal) {
        $MergeLocalColor = if ($FWProfile.AllowLocalPolicyMerge -eq $ExpectMergeLocal) { "Green" } else { "Red" }
        Write-Host "    - AllowLocalPolicyMerge: $($FWProfile.AllowLocalPolicyMerge) (Expected: $ExpectMergeLocal)" -ForegroundColor $MergeLocalColor
        if ($FWProfile.AllowLocalPolicyMerge -ne $ExpectMergeLocal) { $script:Vulnerable = $true }
    }
    if ($null -ne $ExpectMergeIPsec) {
        $MergeIPsecColor = if ($FWProfile.AllowLocalIPsecPolicyMerge -eq $ExpectMergeIPsec) { "Green" } else { "Red" }
        Write-Host "    - AllowLocalIPsecPolicyMerge: $($FWProfile.AllowLocalIPsecPolicyMerge) (Expected: $ExpectMergeIPsec)" -ForegroundColor $MergeIPsecColor
        if ($FWProfile.AllowLocalIPsecPolicyMerge -ne $ExpectMergeIPsec) { $script:Vulnerable = $true }
    }
}

Write-Host "Auditing profiles..." -ForegroundColor Gray
Test-FirewallProfile -ProfileName "Domain" -ExpectMergeLocal $false -ExpectMergeIPsec $false
Test-FirewallProfile -ProfileName "Private" -ExpectMergeLocal $false -ExpectMergeIPsec $false
Test-FirewallProfile -ProfileName "Public" -ExpectMergeLocal $false -ExpectMergeIPsec $false

# Audit outbound rules for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Auditing outbound firewall rules for known LOLBins..." -ForegroundColor Gray

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Rule = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    $Color = "Red"
    
    if ($null -ne $Rule) {
        $ProgFilter = Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $Rule -ErrorAction SilentlyContinue
        $ProgPath = "None"
        if ($null -ne $ProgFilter) {
            $ProgPath = $ProgFilter.Program
        }
        
        if ($Rule.Enabled -eq $true -and $Rule.Direction -eq "Outbound" -and $Rule.Action -eq "Block" -and $ProgPath -eq $Bin.Path) {
            $Color = "Green"
            Write-Host "    - Firewall Rule: $DisplayName | Enabled: True | Action: Block | Program: $ProgPath (Compliant)" -ForegroundColor $Color
        } else {
            $script:Vulnerable = $true
            Write-Host "    - Firewall Rule: $DisplayName | Enabled: $($Rule.Enabled) | Action: $($Rule.Action) | Program: $ProgPath (Non-Compliant)" -ForegroundColor $Color
        }
    } else {
        $script:Vulnerable = $true
        Write-Host "    - Firewall Rule: $DisplayName | NOT FOUND (Non-Compliant)" -ForegroundColor $Color
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawWindowsFirewall.ps1
# Description: Configures Windows Defender Firewall profiles (Domain, Private, Public) and blocks outbound traffic for known LOLBins on PAWs.

Write-Host "Configuring Windows Defender Firewall profiles..." -ForegroundColor Cyan

# 1. Configure profiles
$FWProfiles = @("Domain", "Private", "Public")
foreach ($FWProfile in $FWProfiles) {
    $LogFile = "$env:windir\System32\logfiles\firewall\$($FWProfile.ToLower())fw.log"
    
    Set-NetFirewallProfile -Profile $FWProfile `
        -Enabled True `
        -DefaultInboundAction Block `
        -DefaultOutboundAction Allow `
        -NotifyOnListen False `
        -AllowLocalPolicyMerge False `
        -AllowLocalIPsecPolicyMerge False `
        -LogFileName $LogFile `
        -LogMaxSizeKilobytes 16384 `
        -LogBlocked True `
        -LogAllowed False | Out-Null
    Write-Host "[+] Profile '$FWProfile' configured with logging and defaults." -ForegroundColor Green
}

# 2. Block outbound traffic for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Configuring outbound firewall block rules for known LOLBins..." -ForegroundColor Cyan

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Existing = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -DisplayName $DisplayName `
            -Name $DisplayName `
            -Direction Outbound `
            -Action Block `
            -Program $Bin.Path `
            -Profile Any `
            -Enabled True | Out-Null
        Write-Host "[+] Outbound block rule created for $($Bin.Name)." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -DisplayName $DisplayName -Action Block -Enabled True | Out-Null
        Write-Host "[~] Outbound block rule for $($Bin.Name) already exists, updated state to Enabled/Block." -ForegroundColor Gray
    }
}

Write-Host "Firewall profiles and LOLBins outbound rules configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7027" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-030" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-030] Enable UEFI Secure Boot for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-secure-boot.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Secure Boot is a security standard developed by members of the PC industry to help ensure that a device boots using only software that is trusted by the Original Equipment Manufacturer (OEM).</xhtml:p>
        <xhtml:p>When the PC starts, the firmware checks the signature of each piece of boot software, including UEFI firmware drivers (also known as Option ROMs), EFI applications, and the operating system. If the signatures are valid, the PC boots, and the firmware gives control to the operating system.</xhtml:p>
        <xhtml:p>If Secure Boot is disabled: 1. <xhtml:strong>Bootkits &amp; Rootkits</xhtml:strong>: Attackers with physical access or local administrator privileges can replace the system bootloader with a malicious bootloader (bootkit). This bootkit executes before the Windows operating system loads, allowing it to bypass all Windows security controls, disable antivirus software, and run completely undetected. 2. <xhtml:strong>Virtualization-Based Security</xhtml:strong>: Advanced Windows defenses (like Credential Guard and Device Guard) depend on hardware-rooted trust. If Secure Boot is disabled, Virtualization-Based Security (VBS) cannot verify platform integrity, rendering these protections ineffective.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual UEFI Firmware Configuration (Preferred)</xhtml:h3>
        <xhtml:p>UEFI Secure Boot must be enabled in the hardware firmware menu directly (BIOS settings) during system startup:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Turn on or restart the workstation and access the UEFI utility screen by pressing the vendor-specific key during POST (typically Delete, F2, F10, or F12).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Secure Boot</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure </xhtml:em>
            <xhtml:em>Secure Boot</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure the </xhtml:em>
            <xhtml:em>Secure Boot Mode</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Deployed</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>User Mode</xhtml:em>* (not Setup Mode).</xhtml:li>
          <xhtml:li>Save the configuration and restart the workstation.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Since Secure Boot is a hardware firmware configuration, it cannot be turned on from within Windows using registry settings. However, you can programmatically audit the state of Secure Boot to flag non-compliant hardware.</xhtml:p>
        <xhtml:p>Run the following script to check the status of Secure Boot on the local machine:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-PawSecureBoot.ps1">Download Script: Audit-PawSecureBoot.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-PawSecureBoot.ps1
# Description: Queries UEFI Secure Boot parameters and audits UEFI Secure Boot status.

Write-Host "--- Auditing UEFI Secure Boot ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Verify boot environment type
if ($env:firmware_type -eq "UEFI") {
    Write-Host "    - Boot Environment Type: UEFI" -ForegroundColor Green
} else {
    Write-Host "    - VULNERABLE: System booted in Legacy BIOS mode (CSM enabled) or firmware type is unrecognized." -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Verify Secure Boot status
try {
    # Confirm-SecureBootUEFI returns $true if Secure Boot is active, $false if disabled,
    # and throws an exception if the platform does not support UEFI or Secure Boot.
    $SecureBootState = Confirm-SecureBootUEFI -ErrorAction Stop
    
    $Color = if ($SecureBootState -eq $true) { "Green" } else { "Red" }
    Write-Host "    - Secure Boot Active: $SecureBootState" -ForegroundColor $Color
    if ($SecureBootState -eq $false) { $script:NonCompliant = $true }
} catch [System.PlatformNotSupportedException] {
    Write-Host "    - VULNERABLE: UEFI Secure Boot is not supported on this platform (Legacy BIOS mode)." -ForegroundColor Red
    $script:NonCompliant = $true
} catch {
    # If cmdlet throws unauthorized access or not enabled error
    Write-Host "    - VULNERABLE: Secure Boot is disabled in firmware or cannot be verified. Error: $($_.Exception.Message)" -ForegroundColor Red
    $script:NonCompliant = $true
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7030" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-031" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-031] Enforce Smart Card Logon for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) (Tier 0 Workstations)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enforce-smartcard-logon-paws.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Enforcing smart card requirements at the local operating system level on administrative workstations provides vital physical and logical isolation:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Password Logon Interface Block</xhtml:strong>: Requiring a smart card at logon tells Winlogon to suppress the default username and password fields. This forces the credential provider to only accept certificate-based smart card inserts. An attacker who has somehow acquired a user's password (e.g. via social engineering or physical shoulder surfing) will be unable to log on interactively because the endpoint will not display the password input fields.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Mitigation of Credential Replay Attacks</xhtml:strong>: Traditional password logons store NTHashes locally in the LSA database or cache, which can be extracted by dumping LSASS memory. By using smart card credentials, the logon process utilizes public-key cryptography (Kerberos PKINIT) where the private key never leaves the secure boundaries of the smart card's hardware security chip.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Session Interruption and Removal Enforcement</xhtml:strong>: Enforcing smart card logons naturally aligns with the smart card removal behavior requirement. Removing the smart card locks the session, and re-entry is impossible without physically re-inserting the token and inputting the PIN.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce smart card logon on all PAWs via Group Policy: 1. Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or administrative host. 2. Edit your dedicated PAW Group Policy Object (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>). 3. Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code> 4. In the details pane, double-click <xhtml:strong>Interactive logon: Require smart card</xhtml:strong>. 5. Select <xhtml:strong>Enabled</xhtml:strong> and click <xhtml:strong>OK</xhtml:strong>. 6. Ensure the GPO is linked to the PAW Organizational Unit (OU).</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use these scripts locally on a PAW endpoint to enforce or audit the local smart card requirement.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PAWSmartCardEnforcement.ps1">Download Script: Set-PAWSmartCardEnforcement.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PAWSmartCardEnforcement.ps1
# Description: Configures the registry to require smart cards for interactive logons on PAWs.
# Target Engine: Windows PowerShell 5.1

Write-Host "Enforcing smart card interactive logon requirement..." -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "ScForceOption"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force
Write-Host "Smart card interactive logon requirement applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the local smart card requirement on PAWs:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PAWSmartCardEnforcement.ps1">Download Script: Test-PAWSmartCardEnforcement.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PAWSmartCardEnforcement.ps1
# Description: Audits if the registry is configured to require smart cards for interactive logons on PAWs.
# Target Engine: Windows PowerShell 5.1

Write-Host "--- Auditing PAW Smart Card Interactive Logon Requirement ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "ScForceOption"
$ExpectedValue = 1

$Vulnerable = $false

if (Test-Path $RegPath) {
    $Property = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Property -and $Property.$ValueName -eq $ExpectedValue) {
        Write-Host "    - Registry Setting: $ValueName | Actual: $($Property.$ValueName) (Expected: $ExpectedValue)" -ForegroundColor Green
    } else {
        $actualVal = if ($null -ne $Property) { $Property.$ValueName } else { "Not Found" }
        Write-Host "    - Registry Setting: $ValueName | Actual: $actualVal (Expected: $ExpectedValue)" -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "    - Registry Path: $RegPath | Actual: Path Not Found (Expected: Path Exists)" -ForegroundColor Red
    $Vulnerable = $true
}

if ($Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PAWSmartCardEnforcement.ps1
# Description: Configures the registry to require smart cards for interactive logons on PAWs.
# Target Engine: Windows PowerShell 5.1

Write-Host "Enforcing smart card interactive logon requirement..." -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "ScForceOption"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force
Write-Host "Smart card interactive logon requirement applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7031" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-032" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-032] Disable Unused Windows Features and PowerShell 2.0 Engine</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) (Tier 0 hosts).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/disable-unused-features.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>To enforce strict isolation and minimize the attack surface of Tier 0 Privileged Access Workstations, all unnecessary legacy protocols, optional features, and runtime engines must be disabled.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>PowerShell 2.0 Engine</xhtml:strong>: Legacy PowerShell 2.0 does not support modern logging, transcription, or security monitoring mechanisms such as the Antimalware Scan Interface (AMSI). Attackers leverage "downgrade attacks" by executing PowerShell scripts using the <xhtml:code>-version 2.0</xhtml:code> parameter to bypass script block logging and security tooling. Disabling the engine and its parent runtimes eliminates this bypass vector.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>.NET Framework 3.5</xhtml:strong>: The .NET 3.5 Framework includes the runtime files for .NET 2.0 and 3.0. PowerShell 2.0 requires .NET 2.0/3.5 to run. Disabling <xhtml:code>.NET Framework 3.5</xhtml:code> removes legacy runtime binaries that are susceptible to downgrade attacks and removes support for older, unpatched software.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>SMBv1 Protocol</xhtml:strong>: The legacy SMBv1 protocol is cryptographically weak, lacks authentication integrity protection, and has been the target of catastrophic remote code execution attacks (such as EternalBlue). Leaving the SMBv1 driver active allows relaying and man-in-the-middle attacks.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Internet Explorer 11</xhtml:strong>: Internet Explorer contains obsolete MSHTML render engine components. Disabling this legacy browser reduces vulnerability to web-based code execution.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Work Folders, XPS, DirectPlay, and Client Protocols</xhtml:strong>: Services and tools such as Work Folders, XPS Viewer, DirectPlay, Telnet Client, TFTP Client, and Simple TCP/IP Services contain legacy network parsers and protocols that are completely unnecessary for a secure administrative system.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>WSL and Windows Sandbox</xhtml:strong>: Virtualization layers such as the Windows Subsystem for Linux (WSL) and Windows Sandbox allow the execution of unmonitored binaries, containers, and Linux utilities. On a PAW, these components present an unacceptable audit-bypass risk and must be disabled.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Disable PowerShell 2.0 Compatibility Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the target PAWs GPO (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows PowerShell</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn on PowerShell 2.0 Compatibility Mode</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the PAWs Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Deploy Feature Disablement Startup Script</xhtml:h4>
        <xhtml:p>Because Windows Optional Features are managed via DISM/Packages and lack direct GPO settings for feature removal, deploy the disablement script as a Computer Startup script: 1. In the same GPO, navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Scripts (Startup/Shutdown)</xhtml:code> 2. Double-click <xhtml:strong>Startup</xhtml:strong>, click the <xhtml:strong>PowerShell Scripts</xhtml:strong> tab. 3. Add the <xhtml:code>Disable-PawUnusedFeatures.ps1</xhtml:code> script to execute on system startup.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally or run it as a startup script.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-PawUnusedFeatures.ps1">Download Script: Disable-PawUnusedFeatures.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-PawUnusedFeatures.ps1
# Description: Disables unused legacy features, .NET 3.5, and PowerShell 2.0 on the local PAW system.

Write-Host "Disabling unused legacy features and PowerShell 2.0..." -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

# Features to disable (Client OS DISM feature names)
$Features = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP",                             # Simple TCP/IP Services
    "Microsoft-Windows-Subsystem-Linux",     # WSL (specifically disabled on PAWs)
    "Containers-DisposableClientVM"          # Windows Sandbox (specifically disabled on PAWs)
)

foreach ($Feature in $Features) {
    $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
    if ($null -ne $State) {
        if ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart") {
            Write-Host "[*] Disabling feature: $Feature..." -ForegroundColor Yellow
            Disable-WindowsOptionalFeature -Online -FeatureName $Feature -NoRestart -ErrorAction SilentlyContinue | Out-Null
            Write-Host "[+] Feature '$Feature' has been disabled." -ForegroundColor Green
        } else {
            Write-Host "[~] Feature '$Feature' is already disabled." -ForegroundColor Gray
        }
    } else {
        Write-Host "[~] Feature '$Feature' is not present in this Windows image." -ForegroundColor Gray
    }
}

Write-Host "Optional features configuration completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the state of unused features:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawUnusedFeaturesStatus.ps1">Download Script: Get-PawUnusedFeaturesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawUnusedFeaturesStatus.ps1
# Description: Audits the installation state of unused legacy features on the local PAW system.

Write-Host "--- Auditing Unused Windows Features ---" -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

$script:Vulnerable = $false

# Features to check (Client OS DISM feature names)
$Features = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP",                             # Simple TCP/IP Services
    "Microsoft-Windows-Subsystem-Linux",     # WSL (specifically disabled on PAWs)
    "Containers-DisposableClientVM"          # Windows Sandbox (specifically disabled on PAWs)
)

foreach ($Feature in $Features) {
    $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
    if ($null -ne $State) {
        $IsEnabled = ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart")
        $Color = if (-not $IsEnabled) { "Green" } else { "Red" }
        Write-Host "    - Feature: $Feature | State: $($State.State) (Expected: Disabled)" -ForegroundColor $Color
        
        if ($IsEnabled) {
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - Feature: $Feature | Not Present (Compliant)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-PawUnusedFeatures.ps1
# Description: Disables unused legacy features, .NET 3.5, and PowerShell 2.0 on the local PAW system.

Write-Host "Disabling unused legacy features and PowerShell 2.0..." -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

# Features to disable (Client OS DISM feature names)
$Features = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP",                             # Simple TCP/IP Services
    "Microsoft-Windows-Subsystem-Linux",     # WSL (specifically disabled on PAWs)
    "Containers-DisposableClientVM"          # Windows Sandbox (specifically disabled on PAWs)
)

foreach ($Feature in $Features) {
    $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
    if ($null -ne $State) {
        if ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart") {
            Write-Host "[*] Disabling feature: $Feature..." -ForegroundColor Yellow
            Disable-WindowsOptionalFeature -Online -FeatureName $Feature -NoRestart -ErrorAction SilentlyContinue | Out-Null
            Write-Host "[+] Feature '$Feature' has been disabled." -ForegroundColor Green
        } else {
            Write-Host "[~] Feature '$Feature' is already disabled." -ForegroundColor Gray
        }
    } else {
        Write-Host "[~] Feature '$Feature' is not present in this Windows image." -ForegroundColor Gray
    }
}

Write-Host "Optional features configuration completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7032" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-033" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-033] Configure Microsoft Office Security and Block OLE Packages</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) (Tier 0 Workstations)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-office-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Malicious documents (e.g., weaponized Word, Excel, or PowerPoint files) containing embedded VBA macros are a prevalent initial access and execution vector. Similarly, embedding malicious OLE packages inside Outlook items (such as RTF-formatted emails) allows attackers to trigger script execution or execute arbitrary packages via <xhtml:code>packager.dll</xhtml:code> when an administrator opens or previews the email.</xhtml:p>
        <xhtml:p>Hardening these settings ensures: 1. <xhtml:strong>Internet Macro Blocking</xhtml:strong>: VBA macros in files downloaded from the Internet or untrusted external attachments are blocked from executing, regardless of user consent. 2. <xhtml:strong>Macro Code Signing</xhtml:strong>: Any locally run macros are restricted to trusted, digitally signed code, preventing the execution of ad-hoc unverified user scripts. 3. <xhtml:strong>OLE Package Disablement</xhtml:strong>: Restricting Outlook OLE package activation (<xhtml:code>ShowOLEPackageObj = 0</xhtml:code>) blocks the execution of dangerous embedded objects in email messages.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Enforce Macro Security in ADMX Templates</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO.</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Policies\Administrative Templates\Microsoft Office 2016\Security Settings\Trust Center</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `VBA Macro Notification Settings` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>Disable all except digitally signed macros</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>For each application (Word, Excel, PowerPoint, Access), navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>User Configuration\Policies\Administrative Templates\[Application] 2016\[Application] Options\Security\Trust Center</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Block macros from running in Office files from the Internet` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Disable Outlook OLE Packages</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Policies\Administrative Templates\Microsoft Outlook 2016\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow OLE package execution` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the current user registry hives to enforce macro blocking and OLE package restrictions.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawOfficeSecurity.ps1">Download Script: Configure-PawOfficeSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawOfficeSecurity.ps1
# Description: Configures registry settings under the HKCU hive to restrict VBA macros and block Outlook OLE package execution on PAWs.

Write-Host "Applying Microsoft Office security and OLE restrictions..." -ForegroundColor Cyan

# Helper to configure User Registry DWORD values
function Set-UserRegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$Path,
        [string]$Name,
        [int]$Value
    )
    if ($PSCmdlet.ShouldProcess($Path, "Set registry DWORD value $Name to $Value")) {
        $FullRegistryPath = "HKCU:\$Path"
        if (-not (Test-Path $FullRegistryPath)) {
            New-Item -Path $FullRegistryPath -Force | Out-Null
        }
        Set-ItemProperty -Path $FullRegistryPath -Name $Name -Value $Value -Type DWord -Force
    }
}

# 1. Enforce macro signing policy (common)
Set-UserRegDWord "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3
Write-Host "[+] Digital signing for Office macros enforced." -ForegroundColor Green

# 2. Block macros from the Internet for key Office applications
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Set-UserRegDWord "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}
Write-Host "[+] VBA macro blocks from Internet applied to Office applications." -ForegroundColor Green

# 3. Disable OLE Package execution in Outlook (Policies and Preferences branches)
Set-UserRegDWord "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Set-UserRegDWord "software\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Write-Host "[+] Outlook OLE Package execution blocked." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the current Office security settings:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawOfficeSecurityStatus.ps1">Download Script: Get-PawOfficeSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawOfficeSecurityStatus.ps1
# Description: Audits Microsoft Office macro settings and Outlook OLE package restrictions on PAWs.

Write-Host "--- Auditing Microsoft Office Security Baseline ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper to audit registry values under HKCU
function Test-UserRegistryValue ($Path, $Name, $ExpectedValue) {
    $FullRegistryPath = "HKCU:\$Path"
    $Val = Get-ItemProperty -Path $FullRegistryPath -Name $Name -ErrorAction SilentlyContinue
    $Actual = if ($val) { $val.$Name } else { "" }
    $Color = "Red"
    if ($Actual -eq $ExpectedValue) {
        $Color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - User Registry: $Name | Actual: '$Actual' (Expected: '$ExpectedValue')" -ForegroundColor $Color
}

# 1. Audit macro signing warning
Test-UserRegistryValue "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3

# 2. Audit macro Internet blocks
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Test-UserRegistryValue "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}

# 3. Audit Outlook OLE package block
Test-UserRegistryValue "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawOfficeSecurity.ps1
# Description: Configures registry settings under the HKCU hive to restrict VBA macros and block Outlook OLE package execution on PAWs.

Write-Host "Applying Microsoft Office security and OLE restrictions..." -ForegroundColor Cyan

# Helper to configure User Registry DWORD values
function Set-UserRegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$Path,
        [string]$Name,
        [int]$Value
    )
    if ($PSCmdlet.ShouldProcess($Path, "Set registry DWORD value $Name to $Value")) {
        $FullRegistryPath = "HKCU:\$Path"
        if (-not (Test-Path $FullRegistryPath)) {
            New-Item -Path $FullRegistryPath -Force | Out-Null
        }
        Set-ItemProperty -Path $FullRegistryPath -Name $Name -Value $Value -Type DWord -Force
    }
}

# 1. Enforce macro signing policy (common)
Set-UserRegDWord "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3
Write-Host "[+] Digital signing for Office macros enforced." -ForegroundColor Green

# 2. Block macros from the Internet for key Office applications
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Set-UserRegDWord "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}
Write-Host "[+] VBA macro blocks from Internet applied to Office applications." -ForegroundColor Green

# 3. Disable OLE Package execution in Outlook (Policies and Preferences branches)
Set-UserRegDWord "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Set-UserRegDWord "software\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Write-Host "[+] Outlook OLE Package execution blocked." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7033" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-034" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-034] Disable Windows Script Host and Remap Scripting Extensions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs - Dedicated Tier 0 Administrative Workstations). <xhtml:em>(For Tier 2 Client Workstations, refer to [REQ-END-034](../08-endpoints/disable-windows-script-host.md); for Tier 0 Domain Controllers and Member Servers, refer to [REQ-DC-159](../02-domain-controllers/disable-windows-script-host.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809+), Windows 11 Enterprise (all supported builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/disable-windows-script-host.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated management perimeter for Tier 0 Active Directory assets, enterprise PKI, and virtualization hosts. Because PAWs possess access tokens and administrative credentials with domain-wide authority, eliminating untrusted code execution pathways is paramount:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Elimination of Legacy Scripting Engines</xhtml:strong>: Windows Script Host (<xhtml:code>wscript.exe</xhtml:code> and <xhtml:code>cscript.exe</xhtml:code>) executes legacy VBScript and JScript engines. These hosts are prominent Living-off-the-Land Binaries (LOLBins / LOLBAS) that offer attackers opportunities for defense evasion, memory injection, and unconstrained script execution (MITRE ATT&amp;CK T1059.005, T1059.007, T1218). PAWs have no operational requirement for legacy script execution.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Defense-in-Depth Beyond Application Control</xhtml:strong>: Even in environments where Windows Defender Application Control (WDAC) or AppLocker is deployed, disabling WSH at the registry engine layer ensures that <xhtml:code>wscript.exe</xhtml:code> and <xhtml:code>cscript.exe</xhtml:code> fail immediately upon invocation, preventing script execution even if policies are in audit mode or rule bypasses are attempted.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Comprehensive 64-Bit and WOW6432Node Lockdown</xhtml:strong>: Attackers frequently execute 32-bit binaries (<xhtml:code>%SystemRoot%\SysWOW64\wscript.exe</xhtml:code>) on 64-bit systems to bypass 64-bit security hooks. Enforcing <xhtml:code>Enabled = 0</xhtml:code> and <xhtml:code>TrustPolicy = 2</xhtml:code> across both native 64-bit and WOW6432Node registry paths ensures that 32-bit execution is completely disabled.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>TrustPolicy Hardening</xhtml:strong>: Configuring <xhtml:code>TrustPolicy = 2</xhtml:code> ensures that even if WSH were selectively invoked, unsigned and untrusted scripts are disallowed system-wide.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Fail-Safe File Extension Remapping</xhtml:strong>: Remapping <xhtml:code>.vbs</xhtml:code>, <xhtml:code>.vbe</xhtml:code>, <xhtml:code>.js</xhtml:code>, <xhtml:code>.jse</xhtml:code>, <xhtml:code>.wsf</xhtml:code>, <xhtml:code>.wsh</xhtml:code>, and <xhtml:code>.hta</xhtml:code> file associations to <xhtml:code>txtfile</xhtml:code> (<xhtml:code>notepad.exe</xhtml:code>) ensures that if an administrator inspects an administrative script or artifact, opening the file in Windows Explorer displays the plain text in Notepad rather than executing the script.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Disable WSH via GPO Computer Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong> for the native 64-bit hive:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong> for <xhtml:code>TrustPolicy</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a third <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 disablement:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a fourth <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 TrustPolicy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Disable WSH in User Configuration Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Remap Script File Extensions to Notepad</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Control Panel Settings\Folder Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click and select <xhtml:strong>New -&gt; Open With</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>File Extension</xhtml:em>*: <xhtml:code>vbs</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Associated Program</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\notepad.exe</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set as default</xhtml:em>*: Check</xhtml:li>
          <xhtml:li>Repeat for <xhtml:code>vbe</xhtml:code>, <xhtml:code>js</xhtml:code>, <xhtml:code>jse</xhtml:code>, <xhtml:code>wsf</xhtml:code>, <xhtml:code>wsh</xhtml:code>, and <xhtml:code>hta</xhtml:code>.</xhtml:li>
          <xhtml:li>Alternatively, configure system-wide registry preferences under <xhtml:code>HKLM\SOFTWARE\Classes\.&lt;ext&gt;</xhtml:code> setting the default string value to <xhtml:code>txtfile</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry settings to disable WSH and remap associations.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-PawWsh.ps1">Download Script: Disable-PawWsh.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-PawWsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad on PAWs.

Write-Host "Applying Windows Script Host and file association hardening for PAWs..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the WSH configuration state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PawWshStatus.ps1">Download Script: Get-PawWshStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawWshStatus.ps1
# Description: Audits Windows Script Host registry state across 64-bit and 32-bit hives and script file extension association handlers on PAWs.

Write-Host "--- Auditing Windows Script Host Hardening on PAWs ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# 1. Audit WSH Registry settings in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (Test-Path $RegistryHklm) {
    $ValHklm = (Get-ItemProperty -Path $RegistryHklm -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
    if ($ValHklm -eq 0) {
        Write-Host "    - HKLM WSH Enabled: 0 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH is enabled or not configured (Value: '$($ValHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }

    $TrustHklm = (Get-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
    if ($TrustHklm -eq 2) {
        Write-Host "    - HKLM WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH TrustPolicy is not set to 2 (Value: '$($TrustHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - VULNERABLE: HKLM WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 2. Audit WSH Registry settings in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (Test-Path $RegistryWow64) {
        $ValWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
        if ($ValWow64 -eq 0) {
            Write-Host "    - WOW6432Node WSH Enabled: 0 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH is enabled or not configured (Value: '$($ValWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }

        $TrustWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
        if ($TrustWow64 -eq 2) {
            Write-Host "    - WOW6432Node WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH TrustPolicy is not set to 2 (Value: '$($TrustWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: WOW6432Node WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# 3. Audit file associations
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    if (Test-Path $ProgIdPath) {
        $Handler = (Get-ItemProperty -Path $ProgIdPath -Name "" -ErrorAction SilentlyContinue).""
        if ($Handler -eq "txtfile" -or $Handler -match "notepad") {
            Write-Host "    - Extension .$Ext Handler: $Handler (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: Extension .$Ext Handler is '$($Handler)' (Expected: txtfile/notepad)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: Extension .$Ext Class Registry key not found." -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

if ($script:Vulnerable) {
    Write-Host "[-] Audit Result: VULNERABLE - Windows Script Host hardening controls on PAW do not meet baseline requirements." -ForegroundColor Red
} else {
    Write-Host "[+] Audit Result: SECURE - Windows Script Host hardening controls on PAW are fully compliant." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-PawWsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad on PAWs.

Write-Host "Applying Windows Script Host and file association hardening for PAWs..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7034" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-035" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-035] Configure Secure Boot Revocations and Bootloader Updates for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs).</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-secure-boot-revocations.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>A vulnerability in the Windows Boot Manager allows an attacker with physical access or local administrative rights to bypass UEFI Secure Boot and execute unsigned code during the boot process (BlackLotus bootkit).</xhtml:p>
        <xhtml:p>To fully mitigate this threat (CVE-2023-24932), Windows update revocations must be applied to the UEFI variables (DBX list) and code integrity SVN policies must be updated. This is managed via the <xhtml:code>AvailableUpdates</xhtml:code> registry key, which instructs the OS boot manager to write the revocation variables to firmware.</xhtml:p>
        <xhtml:p>According to the latest Microsoft guidelines, the recommended trigger value for enterprise deployments to apply all security updates (including the new Windows UEFI CA 2023 certificates and boot manager updates) is <xhtml:strong>`0x5944`</xhtml:strong> (hex) / <xhtml:strong>`22852`</xhtml:strong> (decimal). As the OS processes this bitmask, the value is cleared incrementally, ending up at <xhtml:strong>`0x4000`</xhtml:strong> (hex) / <xhtml:strong>`16384`</xhtml:strong> (decimal) upon successful completion.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To configure the update triggers for the DBX and Code Integrity boot manager revocations, define Registry GPO Preferences inside the PAW GPO:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the PAWs OU (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a registry item to deploy the <xhtml:code>AvailableUpdates</xhtml:code> DWORD under <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AvailableUpdates</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>22852</xhtml:code> (Decimal) or <xhtml:code>5944</xhtml:code> (Hex)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the BlackLotus mitigation update trigger:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-PawSecureBootRevocations.ps1">Download Script: Set-PawSecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-PawSecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Audit Script</xhtml:h3>
        <xhtml:p>Run the following script to check the status of Secure Boot revocations on the local machine:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-PawSecureBootRevocations.ps1">Download Script: Audit-PawSecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-PawSecureBootRevocations.ps1
# Description: Queries UEFI Secure Boot parameters and audits BlackLotus mitigation registry settings.

Write-Host "--- Auditing BlackLotus Mitigations ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Audit AvailableUpdates registry key
$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (Test-Path $Path) {
    $Val = Get-ItemProperty -Path $Path -Name "AvailableUpdates" -ErrorAction SilentlyContinue
    $UpdateVal = if ($Val) { $Val.AvailableUpdates } else { 0 }
    
    # Check if configured (&gt;= 0x4000 / 16384)
    if ($UpdateVal -ge 16384) {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Compliant)" -ForegroundColor Green
    } else {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Non-Compliant - DBX/SVN revocations not triggered)" -ForegroundColor Red
        $script:NonCompliant = $true
    }
} else {
    Write-Host "    - BlackLotus Revocation Updates: Registry path not found (Non-Compliant)" -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Audit UEFICA2023Status (if present)
$ServicingPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing"
if (Test-Path $ServicingPath) {
    $ServVal = Get-ItemProperty -Path $ServicingPath -Name "UEFICA2023Status" -ErrorAction SilentlyContinue
    if ($ServVal) {
        $Status = $ServVal.UEFICA2023Status
        $Color = if ($Status -eq "Updated") { "Green" } else { "Yellow" }
        Write-Host "    - UEFI CA 2023 Update Status: $Status" -ForegroundColor $Color
    }
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-PawSecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7035" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-036" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-036] Configure Windows Defender Application Control</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10, Windows 11 (Enterprise and Professional editions)</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/configure-wdac.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated administrative hosts used to manage high-value assets such as Domain Controllers and identity systems. Because they handle Tier 0 administrative credentials, they are highly targeted by adversaries.</xhtml:p>
        <xhtml:p>
          <xhtml:strong>Windows Defender Application Control (WDAC)</xhtml:strong> provides kernel-enforced application control to ensure that only trusted code executes on PAWs. Standard application control options like AppLocker operate primarily in user mode, whereas WDAC enforces integrity at both the kernel (KMCI) and user mode (UMCI) levels. Implementing a baseline WDAC policy that restricts software execution exclusively to Microsoft-signed code and trusted system components blocks unauthorized administrative tools, remote monitoring agents, and malicious payloads.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To deploy WDAC via Group Policy, the policy XML must first be generated, compiled, and placed in a secure shared intranet network path or local path on target hosts.</xhtml:p>
        <xhtml:h4>1. Generate and Compile the Policy (on a Reference PAW Host)</xhtml:h4>
        <xhtml:p>Run the following PowerShell commands to generate the Microsoft Default Windows baseline policy: <xhtml:code />
          <xhtml:code>powershell # Generate the baseline policy XML New-CIPolicy -MultiplePolicyFormat -Level FilePublisher -FilePath "C:\WDAC\PawBaselinePolicy.xml" -UserPEs  # Compile the XML policy into a binary CIP file ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\PawBaselinePolicy.xml" -BinaryFilePath "C:\WDAC\PawBaselinePolicy.cip" </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:h4>2. Deploy the Policy via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Copy the compiled <xhtml:code>PawBaselinePolicy.cip</xhtml:code> file to a local secure directory on all target PAWs (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or host it on a network share.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the PAWs OU (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the local path (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or network share path.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to generate a baseline WDAC policy, enable Audit Mode, and configure local parameters.</xhtml:p>
        <xhtml:h1>Configure-PawWDACLocalPolicy.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawWDACLocalPolicy.ps1">Download Script: Configure-PawWDACLocalPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawWDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy for PAWs, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring PAW WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\PawDefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:h1>Test-PawWDACStatus.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-PawWDACStatus.ps1">Download Script: Test-PawWDACStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-PawWDACStatus.ps1
# Description: Audits the local PAW to check if Code Integrity policies and HVCI are active.

Write-Host "--- Auditing PAW WDAC State ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Query WMI class for Code Integrity status
try {
    $CI = Get-CimInstance -Namespace "Root\Microsoft\Windows\CI" -ClassName "MSFT_Sipolicy" -ErrorAction Stop
    if ($null -ne $CI -and $CI.Count -gt 0) {
        Write-Host "`n[+] Found $($CI.Count) active Code Integrity policies." -ForegroundColor Green
        foreach ($Policy in $CI) {
            Write-Host "    - Policy: $($Policy.FriendlyName) | ID: $($Policy.PolicyID) | Enforced: $($Policy.EnforcementMode)" -ForegroundColor Green
        }
    } else {
        Write-Host "`n[-] No active Code Integrity / WDAC policies detected via WMI." -ForegroundColor Yellow
    }
} catch {
    Write-Host "`n[-] Could not query WMI MSFT_Sipolicy. This is expected if no WDAC policies are currently deployed." -ForegroundColor Gray
}

# 2. Check Memory Integrity (HVCI) configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: One or more driver security controls are not configured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: WDAC driver settings and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawWDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy for PAWs, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring PAW WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\PawDefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7036" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-152" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-152] Account Policy: Password Policy for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-password-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations host the credential material and management tools responsible for enterprise directory survival. While interactive logons on PAWs mandate hardware-backed multi-factor authentication (smart cards / WHfB), local fallback accounts (such as the local Administrator managed by Windows LAPS) must enforce an impervious password baseline to resist offline cryptanalysis:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Password Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce password history</xhtml:em>*: Set to <xhtml:code>24</xhtml:code> passwords remembered</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum password age</xhtml:em>*: Set to <xhtml:code>0</xhtml:code> days (never expire)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minimum password age</xhtml:em>*: Set to <xhtml:code>1</xhtml:code> day</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minimum password length</xhtml:em>*: Set to <xhtml:code>20</xhtml:code> characters</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Password must meet complexity requirements</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Store passwords using reversible encryption</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Relax minimum password length limits</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Prompt user to change password before expiration</xhtml:em>*: Set to <xhtml:code>14</xhtml:code> days</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountPasswordPolicy.ps1">Download Script: Configure-PawAccountPasswordPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountPasswordPolicy.ps1
# Description: Configures PAW password policy (20 char minimum, relaxed limits, no expiration) via SecEdit.

Write-Host "Configuring PAW password policy..." -ForegroundColor Cyan

# 1. Configure PasswordExpiryWarning via Registry
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "PasswordExpiryWarning" -Value 14 -Type DWord -Force

# 2. Configure SecEdit System Access password parameters
$SecTempDir = Join-Path $env:TEMP "PAWPasswordSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "paw_password.cfg"
$DbFile = Join-Path $SecTempDir "paw_password.sdb"
$LogFile = Join-Path $SecTempDir "paw_password.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[System Access\]") {
    $ConfigText += "`r`n[System Access]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InSystemAccess = $false

$PwdSettings = @{
    "MinimumPasswordLength"        = 20
    "PasswordComplexity"           = 1
    "PasswordHistorySize"          = 24
    "MaxPasswordAge"               = 0
    "MinPasswordAge"               = 1
    "ClearTextPassword"            = 0
    "RelaxMinPasswordLengthLimits" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "System Access") {
            $InSystemAccess = $true
        } else {
            $InSystemAccess = $false
        }
    }
    if ($InSystemAccess) {
        $IsManaged = $false
        foreach ($Key in $PwdSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[System Access]") {
        foreach ($Key in $PwdSettings.Keys) {
            $Val = $PwdSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit password policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "PAW password policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountPasswordPolicyStatus.ps1">Download Script: Get-PawAccountPasswordPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountPasswordPolicyStatus.ps1
# Description: Audits PAW password policy parameters via SecEdit and registry queries.

Write-Host "--- Auditing PAW Password Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit Registry Setting
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path -Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $WarnVal = (Get-ItemProperty -Path $WinlogonPath -Name "PasswordExpiryWarning" -ErrorAction SilentlyContinue).PasswordExpiryWarning
    if ($null -eq $WarnVal -or $WarnVal -lt 5 -or $WarnVal -gt 14) {
        Write-Host "    [!] VULNERABLE: PasswordExpiryWarning is set to '$WarnVal' (Expected: 5-14)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] PasswordExpiryWarning: $WarnVal (Secure)" -ForegroundColor Green
    }
}

# 2. Audit SecEdit Settings
$SecTempDir = Join-Path $env:TEMP "PAWPasswordAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "paw_password_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "MinimumPasswordLength"        = 20
    "PasswordComplexity"           = 1
    "PasswordHistorySize"          = 24
    "MaxPasswordAge"               = 0
    "MinPasswordAge"               = 1
    "ClearTextPassword"            = 0
    "RelaxMinPasswordLengthLimits" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the active local password policy settings using <xhtml:code>net accounts</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd net accounts </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>Minimum password length</xhtml:code> reflects <xhtml:code>20</xhtml:code>, <xhtml:code>Length of password history maintained</xhtml:code> is <xhtml:code>24</xhtml:code>, and <xhtml:code>Maximum password age (days)</xhtml:code> indicates <xhtml:code>Unlimited</xhtml:code> (value <xhtml:code>0</xhtml:code>).</xhtml:p>
        <xhtml:p>Verify the password expiration warning registry value: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v PasswordExpiryWarning </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>PasswordExpiryWarning</xhtml:code> is set to <xhtml:code>0xe</xhtml:code> (Decimal <xhtml:code>14</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7152" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-153" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-153] Account Policy: Account Lockout Policy for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-lockout-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Account lockout policies define the defensive response when incorrect credentials are submitted against user accounts. On Privileged Access Workstations, tight lockout thresholds protect administrative credentials from automated brute-force attacks and targeted dictionary probes:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Account Lockout Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account lockout threshold</xhtml:em>*: Set to <xhtml:code>5</xhtml:code> invalid logon attempts</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Reset account lockout counter after</xhtml:em>*: Set to <xhtml:code>30</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account lockout duration</xhtml:em>*: Set to <xhtml:code>30</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Administrator account lockout</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Machine account lockout threshold</xhtml:em>*: Set to <xhtml:code>10</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountLockoutPolicy.ps1">Download Script: Configure-PawAccountLockoutPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountLockoutPolicy.ps1
# Description: Configures account lockout parameters and Administrator lockout protection on PAWs via SecEdit.

Write-Host "Configuring PAW account lockout policy..." -ForegroundColor Cyan

# 1. Configure MaxDevicePasswordFailedAttempts via Registry
$SystemPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path $SystemPolicyPath)) {
    New-Item -Path $SystemPolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $SystemPolicyPath -Name "MaxDevicePasswordFailedAttempts" -Value 10 -Type DWord -Force

# 2. Configure SecEdit System Access lockout parameters
$SecTempDir = Join-Path $env:TEMP "PAWLockoutSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "paw_lockout.cfg"
$DbFile = Join-Path $SecTempDir "paw_lockout.sdb"
$LogFile = Join-Path $SecTempDir "paw_lockout.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[System Access\]") {
    $ConfigText += "`r`n[System Access]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InSystemAccess = $false

$LockoutSettings = @{
    "LockoutBadCount"           = 5
    "ResetLockoutCount"         = 30
    "LockoutDuration"           = 30
    "AllowAdministratorLockout" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "System Access") {
            $InSystemAccess = $true
        } else {
            $InSystemAccess = $false
        }
    }
    if ($InSystemAccess) {
        $IsManaged = $false
        foreach ($Key in $LockoutSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[System Access]") {
        foreach ($Key in $LockoutSettings.Keys) {
            $Val = $LockoutSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit lockout policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "PAW lockout policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountLockoutPolicyStatus.ps1">Download Script: Get-PawAccountLockoutPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountLockoutPolicyStatus.ps1
# Description: Audits account lockout policy parameters on PAWs via SecEdit.

Write-Host "--- Auditing PAW Account Lockout Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit Registry Setting
$SystemPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$MaxDeviceVal = (Get-ItemProperty -Path $SystemPolicyPath -Name "MaxDevicePasswordFailedAttempts" -ErrorAction SilentlyContinue).MaxDevicePasswordFailedAttempts
if ($null -eq $MaxDeviceVal -or $MaxDeviceVal -gt 10 -or $MaxDeviceVal -eq 0) {
    Write-Host "    [!] VULNERABLE: MaxDevicePasswordFailedAttempts is set to '$MaxDeviceVal' (Expected: 10 or fewer, but not 0)" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    Write-Host "    [+] MaxDevicePasswordFailedAttempts: $MaxDeviceVal (Secure)" -ForegroundColor Green
}

# 2. Audit SecEdit Settings
$SecTempDir = Join-Path $env:TEMP "PAWLockoutAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "paw_lockout_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "LockoutBadCount"           = 5
    "ResetLockoutCount"         = 30
    "LockoutDuration"           = 30
    "AllowAdministratorLockout" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied account lockout policies using <xhtml:code>net accounts</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd net accounts </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>Lockout threshold</xhtml:code> shows <xhtml:code>5</xhtml:code>, <xhtml:code>Lockout duration (minutes)</xhtml:code> shows <xhtml:code>30</xhtml:code>, and <xhtml:code>Lockout observation window (minutes)</xhtml:code> shows <xhtml:code>30</xhtml:code>.</xhtml:p>
        <xhtml:p>Verify the machine account lockout threshold registry value: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v MaxDevicePasswordFailedAttempts </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>MaxDevicePasswordFailedAttempts</xhtml:code> is set to <xhtml:code>0xa</xhtml:code> (Decimal <xhtml:code>10</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7153" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-154" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-154] Account Policy: Kerberos Policy for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-kerberos-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kerberos is the foundational authentication protocol of Active Directory Domain Services. Ticket lifetimes and synchronization constraints govern the operational window during which authentication tokens remain valid:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Default Domain Policy or the target GPO linked to PAWs (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Kerberos Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce user logon restrictions</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for service ticket</xhtml:em>*: Set to <xhtml:code>600</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket</xhtml:em>*: Set to <xhtml:code>10</xhtml:code> hours</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket renewal</xhtml:em>*: Set to <xhtml:code>7</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum tolerance for computer clock synchronization</xhtml:em>*: Set to <xhtml:code>5</xhtml:code> minutes</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and force policy update.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountKerberosPolicy.ps1">Download Script: Configure-PawAccountKerberosPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountKerberosPolicy.ps1
# Description: Configures Kerberos ticket lifetimes, renewal limits, and client validation on PAWs via SecEdit.

Write-Host "Configuring PAW Kerberos policy..." -ForegroundColor Cyan

$SecTempDir = Join-Path $env:TEMP "PAWKerberosSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "paw_kerberos.cfg"
$DbFile = Join-Path $SecTempDir "paw_kerberos.sdb"
$LogFile = Join-Path $SecTempDir "paw_kerberos.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Kerberos Policy\]") {
    $ConfigText += "`r`n[Kerberos Policy]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InKerb = $false

$KerbSettings = @{
    "MaxServiceTicketAge"  = 600
    "MaxTicketAge"         = 10
    "MaxRenewAge"          = 7
    "MaxClockSkew"         = 5
    "TicketValidateClient" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Kerberos Policy") {
            $InKerb = $true
        } else {
            $InKerb = $false
        }
    }
    if ($InKerb) {
        $IsManaged = $false
        foreach ($Key in $KerbSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[Kerberos Policy]") {
        foreach ($Key in $KerbSettings.Keys) {
            $Val = $KerbSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit Kerberos policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "PAW Kerberos policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountKerberosPolicyStatus.ps1">Download Script: Get-PawAccountKerberosPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountKerberosPolicyStatus.ps1
# Description: Audits Kerberos ticket policy parameters on PAWs via SecEdit.

Write-Host "--- Auditing PAW Kerberos Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$SecTempDir = Join-Path $env:TEMP "PAWKerberosAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "paw_kerberos_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "MaxServiceTicketAge"  = 600
    "MaxTicketAge"         = 10
    "MaxRenewAge"          = 7
    "MaxClockSkew"         = 5
    "TicketValidateClient" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify current Kerberos ticket lifetimes on the active session using <xhtml:code>klist</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd klist </xhtml:code>
          <xhtml:code /> Inspect the <xhtml:code>Renew Time</xhtml:code> and <xhtml:code>End Time</xhtml:code> of currently cached TGTs to confirm that ticket duration does not exceed 10 hours.</xhtml:p>
        <xhtml:p>To verify domain controller time synchronization: <xhtml:code />
          <xhtml:code>cmd w32tm /query /status </xhtml:code>
          <xhtml:code /> Verify that the <xhtml:code>Leap Indicator</xhtml:code>, <xhtml:code>Stratum</xhtml:code>, and clock offset reflect healthy synchronization with the PDC emulator (offset &lt; 1 second).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7154" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-155" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-155] Account Policy: Smart Card Removal Behavior for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-smart-card-removal.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations serve as high-value execution environments where an active administrative session possesses unconstrained directory authority. Unattended, unlocked consoles present an immediate target for physical tampering, unauthorized keystroke injection (e.g., Rubber Ducky payloads), and unauthorized administrative actions:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Interactive logon: Smart card removal behavior</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and select <xhtml:strong>Lock Workstation</xhtml:strong> (value <xhtml:code>1</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Locate <xhtml:strong>Smart Card Removal Policy</xhtml:strong> service (<xhtml:code>SCPolicySvc</xhtml:code>), configure service startup mode to <xhtml:strong>Automatic</xhtml:strong>, and start the service.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountSmartCardRemoval.ps1">Download Script: Configure-PawAccountSmartCardRemoval.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountSmartCardRemoval.ps1
# Description: Configures Smart Card removal behavior to Lock Workstation and enables SCPolicySvc on PAWs.

Write-Host "Configuring PAW Smart Card removal behavior..." -ForegroundColor Cyan

# 1. Configure Winlogon ScRemoveOption
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "ScRemoveOption" -Value "1" -Type String -Force

# 2. Ensure Smart Card Removal Policy service is configured for Automatic start
$ServiceName = "SCPolicySvc"
$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    Set-Service -Name $ServiceName -StartupType Automatic
    if ($Service.Status -ne "Running") {
        Start-Service -Name $ServiceName -ErrorAction SilentlyContinue
    }
}

Write-Host "Smart card removal behavior set to Lock Workstation ('1') and service configured." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountSmartCardRemovalStatus.ps1">Download Script: Get-PawAccountSmartCardRemovalStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountSmartCardRemovalStatus.ps1
# Description: Audits Smart Card removal behavior and service status on PAWs.

Write-Host "--- Auditing PAW Smart Card Removal Behavior ---" -ForegroundColor Cyan

$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"

if (-not (Test-Path -Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $WinlogonPath -Name "ScRemoveOption" -ErrorAction SilentlyContinue).ScRemoveOption

if ($Val -eq "1") {
    Write-Host "    [+] ScRemoveOption is set to '$Val' (Lock Workstation - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: ScRemoveOption is set to '$Val' (Expected: '1')" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied smart card removal registry setting using command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v ScRemoveOption </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>ScRemoveOption</xhtml:code> is of type <xhtml:code>REG_SZ</xhtml:code> with value <xhtml:code>"1"</xhtml:code>.</xhtml:p>
        <xhtml:p>Verify the Smart Card Removal Policy service status: <xhtml:code />
          <xhtml:code>cmd sc query SCPolicySvc </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>STATE</xhtml:code> indicates <xhtml:code>RUNNING</xhtml:code> and <xhtml:code>START_TYPE</xhtml:code> is <xhtml:code>AUTO_START</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7155" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-156" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-156] Account Policy: Cached Logons and PBKDF2 Iteration Count for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-cached-logons.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>By default, Windows caches authentication verifiers for previously logged-on domain accounts to permit user authentication when an Active Directory Domain Controller cannot be reached. On Privileged Access Workstations, this feature poses an existential risk to Tier 0 directory security:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Interactive logon: Number of previous logons to cache (in case domain controller is not available)</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and set the cache value to <xhtml:strong>0</xhtml:strong> logons.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SECURITY\Cache</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>NL$IterationCount</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>1954</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and verify application using <xhtml:code>gpresult /r</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountCachedLogons.ps1">Download Script: Configure-PawAccountCachedLogons.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountCachedLogons.ps1
# Description: Disables cached domain logons and fortifies PBKDF2 iteration count on PAWs.

Write-Host "Configuring PAW cached logon restrictions and PBKDF2 iterations..." -ForegroundColor Cyan

# 1. Disable cached logons count
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path -Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "CachedLogonsCount" -Value 0 -Type DWord -Force

# 2. Configure PBKDF2 Iteration Count
$CachePath = "HKLM:\SECURITY\Cache"
if (-not (Test-Path -Path $CachePath)) {
    New-Item -Path $CachePath -Force | Out-Null
}
Set-ItemProperty -Path $CachePath -Name "NL`$IterationCount" -Value 1954 -Type DWord -Force

Write-Host "Cached logons count disabled (0) and PBKDF2 iteration count configured (1954)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountCachedLogonsStatus.ps1">Download Script: Get-PawAccountCachedLogonsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountCachedLogonsStatus.ps1
# Description: Audits cached logons count and PBKDF2 iteration count on PAWs.

Write-Host "--- Auditing PAW Cached Logons and PBKDF2 Settings ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit CachedLogonsCount
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path -Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $CacheCount = (Get-ItemProperty -Path $WinlogonPath -Name "CachedLogonsCount" -ErrorAction SilentlyContinue).CachedLogonsCount
    if ($CacheCount -ne 0) {
        Write-Host "    [!] VULNERABLE: CachedLogonsCount is '$CacheCount' (Expected: 0)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] CachedLogonsCount: 0 (Secure - Cache Disabled)" -ForegroundColor Green
    }
}

# 2. Audit NL$IterationCount
$CachePath = "HKLM:\SECURITY\Cache"
if (-not (Test-Path -Path $CachePath)) {
    Write-Host "    [!] MISSING KEY: $CachePath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $IterCount = (Get-ItemProperty -Path $CachePath -Name "NL`$IterationCount" -ErrorAction SilentlyContinue)."NL`$IterationCount"
    if ($IterCount -ne 1954) {
        Write-Host "    [!] VULNERABLE: NL`$IterationCount is '$IterCount' (Expected: 1954)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] NL`$IterationCount: 1954 (Secure - ~2M PBKDF2 Iterations)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied settings using administrative command line queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v CachedLogonsCount </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>CachedLogonsCount</xhtml:code> returns <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:p>To inspect the <xhtml:code>SECURITY\Cache</xhtml:code> key (requires elevated privileges via <xhtml:code>psexec -s cmd.exe</xhtml:code> or SYSTEM context): <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SECURITY\Cache" /v NL$IterationCount </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>NL$IterationCount</xhtml:code> returns <xhtml:code>0x7a2</xhtml:code> (Decimal <xhtml:code>1954</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7156" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-157" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-157] Account Policy: Local Accounts and Blank Password Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-local-blank-passwords.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Restricting local account authentication boundaries, disabling legacy password hashes, and enforcing explicit user identity validation are vital to securing Tier 0 administrative workstations against remote compromise:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Accounts: Limit local account use of blank passwords to console logon only</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Do not store LAN Manager hash value on next password change</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Sharing and security model for local accounts</xhtml:em>*: Set to <xhtml:code>Classic - local users authenticate as themselves</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountLocalBlankPasswords.ps1">Download Script: Configure-PawAccountLocalBlankPasswords.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountLocalBlankPasswords.ps1
# Description: Enforces blank password restrictions, purges LM hashes, and sets Classic sharing on PAWs.

Write-Host "Configuring PAW local account and blank password restrictions..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path -Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "LimitBlankPasswordUse" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "NoLMHash" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "ForceNetworkLogon" -Value 0 -Type DWord -Force

Write-Host "Local account and blank password restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountLocalBlankPasswordsStatus.ps1">Download Script: Get-PawAccountLocalBlankPasswordsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountLocalBlankPasswordsStatus.ps1
# Description: Audits local account restrictions, LM hash generation, and sharing model on PAWs.

Write-Host "--- Auditing PAW Local Account and Blank Password Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"

function Test-RegVal ($Name, $Expected) {
    if (-not (Test-Path -Path $LsaPath)) {
        Write-Host "    [!] MISSING KEY: $LsaPath" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $LsaPath -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $LsaPath (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "LimitBlankPasswordUse" 1
Test-RegVal "NoLMHash" 1
Test-RegVal "ForceNetworkLogon" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v NoLMHash reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v ForceNetworkLogon </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>LimitBlankPasswordUse</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>NoLMHash</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>ForceNetworkLogon</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7157" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-158" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-158] Account Policy: NTLM and LAN Manager Authentication Security for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-ntlm-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Legacy LAN Manager (LM) and NT LAN Manager version 1 (NTLMv1) authentication protocols are critically vulnerable to cryptographic recovery, offline dictionary cracking, and man-in-the-middle relaying. On Tier 0 Privileged Access Workstations, legacy authentication must be purged and session security fortified:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: LAN Manager authentication level</xhtml:em>*: Set to <xhtml:code>Send NTLMv2 response only. Refuse LM &amp; NTLM</xhtml:code> (value <xhtml:code>5</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Minimum session security for NTLM SSP based (including secure RPC) clients</xhtml:em>*: Check both <xhtml:code>Require NTLMv2 session security</xhtml:code> and <xhtml:code>Require 128-bit encryption</xhtml:code> (value <xhtml:code>537395200</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Minimum session security for NTLM SSP based (including secure RPC) servers</xhtml:em>*: Check both <xhtml:code>Require NTLMv2 session security</xhtml:code> and <xhtml:code>Require 128-bit encryption</xhtml:code> (value <xhtml:code>537395200</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Allow LocalSystem NULL session fallback</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountNtlmSecurity.ps1">Download Script: Configure-PawAccountNtlmSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountNtlmSecurity.ps1
# Description: Enforces NTLMv2-only authentication, 128-bit session security, and blocks NULL session fallback on PAWs.

Write-Host "Configuring PAW NTLM and LAN Manager authentication security..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path -Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "LmCompatibilityLevel" -Value 5 -Type DWord -Force

$MsvPath = "HKLM:\System\CurrentControlSet\Control\Lsa\MSV1_0"
if (-not (Test-Path $MsvPath)) {
    New-Item -Path $MsvPath -Force | Out-Null
}
Set-ItemProperty -Path $MsvPath -Name "NTLMMinClientSec" -Value 537395200 -Type DWord -Force
Set-ItemProperty -Path $MsvPath -Name "NTLMMinServerSec" -Value 537395200 -Type DWord -Force
Set-ItemProperty -Path $MsvPath -Name "allownullsessionfallback" -Value 0 -Type DWord -Force

Write-Host "NTLM and LAN Manager authentication security applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountNtlmSecurityStatus.ps1">Download Script: Get-PawAccountNtlmSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountNtlmSecurityStatus.ps1
# Description: Audits NTLM authentication levels, session security, and NULL session fallback on PAWs.

Write-Host "--- Auditing PAW NTLM and LAN Manager Security ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$MsvPath = "HKLM:\System\CurrentControlSet\Control\Lsa\MSV1_0"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $LsaPath "LmCompatibilityLevel" 5
Test-RegVal $MsvPath "NTLMMinClientSec" 537395200
Test-RegVal $MsvPath "NTLMMinServerSec" 537395200
Test-RegVal $MsvPath "allownullsessionfallback" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied NTLM settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v LmCompatibilityLevel reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v NTLMMinClientSec reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v NTLMMinServerSec reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v allownullsessionfallback </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>LmCompatibilityLevel</xhtml:code> is <xhtml:code>0x5</xhtml:code>, <xhtml:code>NTLMMinClientSec</xhtml:code> and <xhtml:code>NTLMMinServerSec</xhtml:code> are <xhtml:code>0x20080000</xhtml:code> (Decimal <xhtml:code>537395200</xhtml:code>), and <xhtml:code>allownullsessionfallback</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7158" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-159" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-159] Account Policy: Disable WDigest Credential Caching for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-wdigest-credentials.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (LSASS) manages active logon sessions and authentication tokens. In legacy Windows architectures, the WDigest provider retained cleartext passwords in memory, creating one of the most prolific post-exploitation attack vectors in Windows history:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>UseLogonCredential</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountWdigestCredentials.ps1">Download Script: Configure-PawAccountWdigestCredentials.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountWdigestCredentials.ps1
# Description: Disables WDigest plaintext credential caching in LSASS memory on PAWs.

Write-Host "Disabling WDigest plaintext credential caching on PAWs..." -ForegroundColor Cyan

$WDigestPath = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\WDigest"
if (-not (Test-Path $WDigestPath)) {
    New-Item -Path $WDigestPath -Force | Out-Null
}
Set-ItemProperty -Path $WDigestPath -Name "UseLogonCredential" -Value 0 -Type DWord -Force

Write-Host "WDigest credential caching disabled successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountWdigestCredentialsStatus.ps1">Download Script: Get-PawAccountWdigestCredentialsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountWdigestCredentialsStatus.ps1
# Description: Audits WDigest plaintext credential caching status on PAWs.

Write-Host "--- Auditing PAW WDigest Credential Caching ---" -ForegroundColor Cyan

$WDigestPath = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\WDigest"

if (-not (Test-Path -Path $WDigestPath)) {
    Write-Host "    [!] MISSING KEY: $WDigestPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $WDigestPath -Name "UseLogonCredential" -ErrorAction SilentlyContinue).UseLogonCredential

if ($null -ne $Val -and $Val -eq 0) {
    Write-Host "    [+] UseLogonCredential is set to 0 (Disabled - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: UseLogonCredential is '$Val' (Expected: 0)" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied WDigest setting using command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\SecurityProviders\WDigest" /v UseLogonCredential </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>UseLogonCredential</xhtml:code> is of type <xhtml:code>REG_DWORD</xhtml:code> with a value of <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7159" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-160" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-160] Account Policy: Windows Hello for Business and PIN Complexity for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-hello-pin.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modern credential protection relies on hardware-bound asymmetric cryptographic tokens rather than reusable passwords. However, legacy convenience features and unhardened PIN mechanisms can undermine this architecture if not strictly configured on administrative workstations:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure System Logon policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Logon</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Turn on convenience PIN sign-in</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Configure PIN Complexity policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\PIN Complexity</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Minimum PIN length</xhtml:em>
            <xhtml:em>, set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*, and enter <xhtml:code>6</xhtml:code>.</xhtml:li>
          <xhtml:li>Configure Windows Hello for Business policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Hello for Business</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Use a hardware security device</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Use convenience PIN sign-in</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Allow Microsoft accounts to be optional</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and verify enforcement.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountHelloPin.ps1">Download Script: Configure-PawAccountHelloPin.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountHelloPin.ps1
# Description: Hardens Windows Hello for Business, disables convenience PINs, and mandates TPM hardware backing on PAWs.

Write-Host "Configuring PAW Windows Hello for Business and PIN policies..." -ForegroundColor Cyan

# 1. System Logon PIN Policy
$SysPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SysPath)) {
    New-Item -Path $SysPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPath -Name "AllowDomainPINLogon" -Value 0 -Type DWord -Force

# 2. PIN Complexity
$PinPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity"
if (-not (Test-Path $PinPath)) {
    New-Item -Path $PinPath -Force | Out-Null
}
Set-ItemProperty -Path $PinPath -Name "MinimumPINLength" -Value 6 -Type DWord -Force

# 3. Hardware Security Device
$PfwPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork"
if (-not (Test-Path $PfwPath)) {
    New-Item -Path $PfwPath -Force | Out-Null
}
Set-ItemProperty -Path $PfwPath -Name "RequireSecurityDevice" -Value 1 -Type DWord -Force

$TpmPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\ExcludeSecurityDevices"
if (-not (Test-Path $TpmPath)) {
    New-Item -Path $TpmPath -Force | Out-Null
}
Set-ItemProperty -Path $TpmPath -Name "TPM12" -Value 0 -Type DWord -Force

# 4. MSA Optional
$SysPolPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path $SysPolPath)) {
    New-Item -Path $SysPolPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPolPath -Name "MSAOptional" -Value 1 -Type DWord -Force

Write-Host "Windows Hello and PIN policies applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountHelloPinStatus.ps1">Download Script: Get-PawAccountHelloPinStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountHelloPinStatus.ps1
# Description: Audits Windows Hello for Business, PIN complexity, and TPM enforcement status on PAWs.

Write-Host "--- Auditing PAW Windows Hello and PIN Policies ---" -ForegroundColor Cyan
$script:Vulnerable = $false

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "AllowDomainPINLogon" 0
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity" "MinimumPINLength" 6
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork" "RequireSecurityDevice" 1
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\ExcludeSecurityDevices" "TPM12" 0
Test-RegVal "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "MSAOptional" 1

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policies using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v AllowDomainPINLogon reg query "HKLM\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity" /v MinimumPINLength reg query "HKLM\SOFTWARE\Policies\Microsoft\PassportForWork" /v RequireSecurityDevice reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v MSAOptional </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>AllowDomainPINLogon</xhtml:code> returns <xhtml:code>0x0</xhtml:code>, <xhtml:code>MinimumPINLength</xhtml:code> returns <xhtml:code>0x6</xhtml:code>, <xhtml:code>RequireSecurityDevice</xhtml:code> returns <xhtml:code>0x1</xhtml:code>, and <xhtml:code>MSAOptional</xhtml:code> returns <xhtml:code>0x1</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7160" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-161" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-161] Account Policy: Consumer Microsoft Account Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-block-msa.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations serve as the dedicated management plane for Active Directory Domain Controllers, Tier 0 PKI, and identity federation infrastructure. Introducing consumer cloud identities into this trusted boundary creates critical security exposures:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Microsoft Account</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Block all consumer Microsoft account user authentication</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set the policy to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and verify policy propagation.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountBlockMsa.ps1">Download Script: Configure-PawAccountBlockMsa.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountBlockMsa.ps1
# Description: Blocks consumer Microsoft account user authentication on PAWs.

Write-Host "Blocking consumer Microsoft account user authentication on PAWs..." -ForegroundColor Cyan

$MsaPath = "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftAccount"
if (-not (Test-Path -Path $MsaPath)) {
    New-Item -Path $MsaPath -Force | Out-Null
}
Set-ItemProperty -Path $MsaPath -Name "DisableUserAuth" -Value 1 -Type DWord -Force

Write-Host "Consumer Microsoft account user authentication blocked successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountBlockMsaStatus.ps1">Download Script: Get-PawAccountBlockMsaStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountBlockMsaStatus.ps1
# Description: Audits consumer Microsoft account blocking status on PAWs.

Write-Host "--- Auditing PAW Consumer Microsoft Account Restrictions ---" -ForegroundColor Cyan

$MsaPath = "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftAccount"

if (-not (Test-Path -Path $MsaPath)) {
    Write-Host "    [!] MISSING KEY: $MsaPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $MsaPath -Name "DisableUserAuth" -ErrorAction SilentlyContinue).DisableUserAuth

if ($null -ne $Val -and $Val -eq 1) {
    Write-Host "    [+] DisableUserAuth is set to 1 (Enabled - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: DisableUserAuth is '$Val' (Expected: 1)" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy via command prompt using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftAccount" /v DisableUserAuth </xhtml:code>
          <xhtml:code /> Confirm that the value <xhtml:code>DisableUserAuth</xhtml:code> is of type <xhtml:code>REG_DWORD</xhtml:code> and set to <xhtml:code>0x1</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7161" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-162" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-162] Account Policy: Domain Member Secure Channel Security for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-secure-channel.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Netlogon Remote Protocol (MS-NRPC) secure channel forms the cryptographic communication link between domain-joined workstations and Active Directory Domain Controllers. On Privileged Access Workstations, protecting this channel from tampering, session key downgrade, and credential stagnation is essential to directory integrity:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally encrypt or sign secure channel data (always)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally encrypt secure channel data (when possible)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally sign secure channel data (when possible)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Disable machine account password changes</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Maximum machine account password age</xhtml:em>*: Set to <xhtml:code>30</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Require strong (Windows 2000 or later) session key</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountSecureChannel.ps1">Download Script: Configure-PawAccountSecureChannel.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountSecureChannel.ps1
# Description: Configures Netlogon secure channel signing, sealing, strong keys, and password rotation on PAWs.

Write-Host "Configuring PAW Domain Member Secure Channel settings..." -ForegroundColor Cyan

$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path -Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}

Set-ItemProperty -Path $NetlogonPath -Name "RequireSignOrSeal" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "SealSecureChannel" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "SignSecureChannel" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "DisablePasswordChange" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "MaximumPasswordAge" -Value 30 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "RequireStrongKey" -Value 1 -Type DWord -Force

Write-Host "Domain Member Secure Channel settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountSecureChannelStatus.ps1">Download Script: Get-PawAccountSecureChannelStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountSecureChannelStatus.ps1
# Description: Audits Netlogon secure channel parameters on PAWs.

Write-Host "--- Auditing PAW Domain Member Secure Channel Settings ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $NetlogonPath "RequireSignOrSeal" 1
Test-RegVal $NetlogonPath "SealSecureChannel" 1
Test-RegVal $NetlogonPath "SignSecureChannel" 1
Test-RegVal $NetlogonPath "DisablePasswordChange" 0
Test-RegVal $NetlogonPath "MaximumPasswordAge" 30
Test-RegVal $NetlogonPath "RequireStrongKey" 1

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the active secure channel configuration using <xhtml:code>nltest</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd nltest /sc_query:%USERDNSDOMAIN% nltest /sc_verify:%USERDNSDOMAIN% </xhtml:code>
          <xhtml:code /> Confirm that the secure channel is verified with a trusted Domain Controller and returns status <xhtml:code>NTRR_SUCCESS</xhtml:code> (or <xhtml:code>0x0</xhtml:code>).</xhtml:p>
        <xhtml:p>Verify the applied registry settings using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v RequireSignOrSeal reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v RequireStrongKey reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v MaximumPasswordAge </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>RequireSignOrSeal</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>RequireStrongKey</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>MaximumPasswordAge</xhtml:code> is <xhtml:code>0x1e</xhtml:code> (Decimal <xhtml:code>30</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7162" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-163" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-163] Account Policy: SMB Client and Server Security Options for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-smb-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Server Message Block (SMB) protocol is utilized extensively for administrative file transfers, Group Policy retrieval, and remote management. Hardening SMB client and server parameters on Privileged Access Workstations prevents cleartext credential exposure, terminates stale dormant sessions, and eliminates unauthenticated network shares:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network client: Send unencrypted password to third-party SMB servers</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Amount of idle time required before suspending session</xhtml:em>*: Set to <xhtml:code>15</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Disconnect clients when logon hours expire</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Force logoff when logon hours expire</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Shares that can be accessed anonymously</xhtml:em>*: Set to <xhtml:code>None</xhtml:code> (leave field completely empty)</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountSmbSecurity.ps1">Download Script: Configure-PawAccountSmbSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountSmbSecurity.ps1
# Description: Configures SMB client and server security options (plaintext block, auto-disconnect, logon hours) on PAWs.

Write-Host "Configuring PAW SMB client and server security options..." -ForegroundColor Cyan

# 1. LanmanWorkstation: Block plaintext passwords
$WorkstationPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
if (-not (Test-Path -Path $WorkstationPath)) {
    New-Item -Path $WorkstationPath -Force | Out-Null
}
Set-ItemProperty -Path $WorkstationPath -Name "EnablePlainTextPassword" -Value 0 -Type DWord -Force

# 2. LanmanServer: AutoDisconnect, EnableForcedLogoff, NullSessionShares
$ServerPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path -Path $ServerPath)) {
    New-Item -Path $ServerPath -Force | Out-Null
}
Set-ItemProperty -Path $ServerPath -Name "AutoDisconnect" -Value 15 -Type DWord -Force
Set-ItemProperty -Path $ServerPath -Name "EnableForcedLogoff" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ServerPath -Name "NullSessionShares" -Value @() -Type MultiString -Force

# 3. Netlogon: ForceLogoffWhenHourExpire
$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path -Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $NetlogonPath -Name "ForceLogoffWhenHourExpire" -Value 1 -Type DWord -Force

Write-Host "SMB client and server security options applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountSmbSecurityStatus.ps1">Download Script: Get-PawAccountSmbSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountSmbSecurityStatus.ps1
# Description: Audits SMB client and server security options on PAWs.

Write-Host "--- Auditing PAW SMB Client and Server Security Options ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$WorkstationPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
$ServerPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $WorkstationPath "EnablePlainTextPassword" 0
Test-RegVal $ServerPath "AutoDisconnect" 15
Test-RegVal $ServerPath "EnableForcedLogoff" 1
Test-RegVal $NetlogonPath "ForceLogoffWhenHourExpire" 1

# Audit NullSessionShares
if (Test-Path -Path $ServerPath) {
    $NullShares = (Get-ItemProperty -Path $ServerPath -Name "NullSessionShares" -ErrorAction SilentlyContinue).NullSessionShares
    if ($null -ne $NullShares -and $NullShares.Count -gt 0 -and ($NullShares -join "") -ne "") {
        Write-Host "    [!] VULNERABLE: NullSessionShares contains: $($NullShares -join ', ')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] NullSessionShares: Empty (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied SMB settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v EnablePlainTextPassword reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v AutoDisconnect reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v EnableForcedLogoff reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v ForceLogoffWhenHourExpire reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v NullSessionShares </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>EnablePlainTextPassword</xhtml:code> is <xhtml:code>0x0</xhtml:code>, <xhtml:code>AutoDisconnect</xhtml:code> is <xhtml:code>0xf</xhtml:code> (Decimal <xhtml:code>15</xhtml:code>), <xhtml:code>EnableForcedLogoff</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>ForceLogoffWhenHourExpire</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>NullSessionShares</xhtml:code> is empty.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7163" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-164" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-164] Account Policy: Anonymous Access and Enumeration Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-anonymous-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Unauthenticated network enumeration provides initial access actors with reconnaissance data required to map administrative privileges, local accounts, and shared directory resources:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Do not allow anonymous enumeration of SAM accounts</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Do not allow anonymous enumeration of SAM accounts and shares</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Allow anonymous SID/Name translation</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Allow PKU2U authentication requests to this computer to use online identities</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>System objects: Require case insensitivity for non-Windows subsystems</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force replication across Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountAnonymousRestrictions.ps1">Download Script: Configure-PawAccountAnonymousRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountAnonymousRestrictions.ps1
# Description: Hardens anonymous access, SAM enumeration, PKU2U, and subsystem object naming on PAWs.

Write-Host "Configuring PAW anonymous access and enumeration restrictions..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path -Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "RestrictAnonymousSAM" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "RestrictAnonymous" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "ObaseCaseInsensitive" -Value 1 -Type DWord -Force

$KerbPath = "HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters"
if (-not (Test-Path -Path $KerbPath)) {
    New-Item -Path $KerbPath -Force | Out-Null
}
Set-ItemProperty -Path $KerbPath -Name "AllowPKU2U" -Value 0 -Type DWord -Force

Write-Host "Anonymous access and enumeration restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountAnonymousRestrictionsStatus.ps1">Download Script: Get-PawAccountAnonymousRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountAnonymousRestrictionsStatus.ps1
# Description: Audits PAW anonymous enumeration, PKU2U, and subsystem object security configuration.

Write-Host "--- Auditing PAW Anonymous Access and Enumeration Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$KerbPath = "HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $LsaPath "RestrictAnonymousSAM" 1
Test-RegVal $LsaPath "RestrictAnonymous" 1
Test-RegVal $LsaPath "ObaseCaseInsensitive" 1
Test-RegVal $KerbPath "AllowPKU2U" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry values via command prompt using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymousSAM reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v ObaseCaseInsensitive reg query "HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters" /v AllowPKU2U </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>RestrictAnonymousSAM</xhtml:code>, <xhtml:code>RestrictAnonymous</xhtml:code>, and <xhtml:code>ObaseCaseInsensitive</xhtml:code> return <xhtml:code>0x1</xhtml:code>, and <xhtml:code>AllowPKU2U</xhtml:code> returns <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7164" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-165" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-165] Account Policy: Interactive Logon Security Options for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above), Windows 11 Enterprise (all builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/account-policy/configure-paw-account-interactive-logon.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Interactive logon controls establish the initial verification boundary between the physical user, hardware input devices, and the Windows kernel. On Tier 0 Privileged Access Workstations, interactive logon settings must eliminate credential harvesting prompts, shoulder surfing, and denial-of-service vectors:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the PAW GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Do not require CTRL+ALT+DEL</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Don't display last signed-in</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code> (value <xhtml:code>1</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Audit: Shut down system immediately if unable to log security audits</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW OU and force update via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAccountInteractiveLogon.ps1">Download Script: Configure-PawAccountInteractiveLogon.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawAccountInteractiveLogon.ps1
# Description: Configures interactive logon security options (SAS requirement, hide last user, audit stability) on PAWs.

Write-Host "Configuring PAW interactive logon security options..." -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path -Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

Set-ItemProperty -Path $SystemPath -Name "DisableCAD" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $SystemPath -Name "DontDisplayLastUserName" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $SystemPath -Name "CrashOnAuditFail" -Value 0 -Type DWord -Force

Write-Host "Interactive logon security options applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAccountInteractiveLogonStatus.ps1">Download Script: Get-PawAccountInteractiveLogonStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawAccountInteractiveLogonStatus.ps1
# Description: Audits interactive logon security options on PAWs.

Write-Host "--- Auditing PAW Interactive Logon Security Options ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

function Test-RegVal ($Name, $Expected) {
    if (-not (Test-Path -Path $SystemPath)) {
        Write-Host "    [!] MISSING KEY: $SystemPath" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $SystemPath -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $SystemPath (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "DisableCAD" 0
Test-RegVal "DontDisplayLastUserName" 1
Test-RegVal "CrashOnAuditFail" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry configuration using command line queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DisableCAD reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DontDisplayLastUserName reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v CrashOnAuditFail </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>DisableCAD</xhtml:code> is <xhtml:code>0x0</xhtml:code>, <xhtml:code>DontDisplayLastUserName</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>CrashOnAuditFail</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7165" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-167" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-167] Enable Kerberos Armoring for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) (Tier 0 Workstations)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise, Windows 11 Enterprise</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/enable-kerberos-armoring.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) host high-privilege administrative sessions used to manage Active Directory Domain Controllers and Tier 0 identity infrastructure. Standard Kerberos pre-authentication transmits the initial authentication request (AS-REQ) containing timestamp data that can be intercepted by adversaries monitoring network traffic, facilitating offline dictionary attacks and password cracking. Furthermore, accounts configured without Kerberos pre-authentication (<xhtml:code>DONT_REQ_PREAUTH</xhtml:code>) remain susceptible to AS-REP roasting attacks.</xhtml:p>
        <xhtml:p>Kerberos Armoring, or Flexible Authentication Secure Tunneling (FAST - RFC 6113), establishes an encrypted channel between the Kerberos client and the Key Distribution Center (KDC) using the client computer's account credential or machine certificate. This protects the AS-REQ and AS-REP exchanges against sniffing, offline cracking, and message tampering.</xhtml:p>
        <xhtml:p>In accordance with Tier 0 hardening baselines, the PAW configuration is strictly tightened compared to standard end-user workstations. While standard endpoints negotiate FAST opportunistically, PAWs configure <xhtml:strong>Fail authentication requests when Kerberos armoring is not available</xhtml:strong> (<xhtml:code>RequireFast = 1</xhtml:code>). This policy mandates that all authentication service (AS) and ticket-granting service (TGS) exchanges must be armored. If a Domain Controller does not support FAST or an attacker attempts a protocol downgrade, authentication is immediately terminated, ensuring that Tier 0 credentials are never exposed over unarmored channels.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a Tier 0 management host.</xhtml:li>
          <xhtml:li>Edit the dedicated PAW Computer Hardening GPO (e.g., <xhtml:code>GPO_Hardening_PAW_Computers</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Kerberos</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Kerberos client support for claims, compound authentication and Kerberos armoring` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Support device authentication using certificate` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>Automatic</xhtml:code> in options)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Fail authentication requests when Kerberos armoring is not available` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Link the GPO to the <xhtml:strong>Tier 0 PAWs</xhtml:strong> Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for standalone PAW provisioning or gold image preparation) or if the control is not manageable via standard GPO interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PawKerberosArmoring.ps1">Download Script: Configure-PawKerberosArmoring.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PawKerberosArmoring.ps1
# Description: Configures Kerberos Armoring (FAST) with strict enforcement and certificate device authentication on PAWs.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring (FAST) on PAWs..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}

# 1. Enable Kerberos client support for claims and armoring
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord

# 2. Support device authentication using certificate (Automatic)
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord

# 3. Fail authentication requests when Kerberos armoring is not available (Strict FAST enforcement on Tier 0 PAWs)
Set-ItemProperty -Path $ClientRegPath -Name "RequireFast" -Value 1 -Type DWord

Write-Host "PAW Kerberos Armoring configured successfully with strict enforcement (RequireFast = 1)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-PawKerberosArmoringStatus.ps1">Download Script: Get-PawKerberosArmoringStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PawKerberosArmoringStatus.ps1
# Description: Audits Kerberos Armoring (FAST) configuration on Privileged Access Workstations (PAWs).

Write-Host "--- Auditing PAW Kerberos Armoring Configuration ---" -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$Vulnerable = $false

$ClientValue = Get-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue
$DevicePKInit = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -ErrorAction SilentlyContinue
$DeviceBehavior = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -ErrorAction SilentlyContinue
$RequireFast = Get-ItemProperty -Path $ClientRegPath -Name "RequireFast" -ErrorAction SilentlyContinue

# 1. Audit Client-side support for claims and armoring
if ($null -ne $ClientValue -and $ClientValue.EnableCbacAndArmor -eq 1) {
    Write-Host "[+] Client-side Kerberos Armoring is ENABLED (EnableCbacAndArmor = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Client-side Kerberos Armoring is DISABLED or missing." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Audit Certificate device authentication
if ($null -ne $DevicePKInit -and $DevicePKInit.DevicePKInitEnabled -eq 1 -and $null -ne $DeviceBehavior -and $DeviceBehavior.DevicePKInitBehavior -eq 0) {
    Write-Host "[+] Certificate device authentication is ENABLED: Automatic." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Certificate device authentication is not compliant or not configured." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Audit Strict Armoring Enforcement (RequireFast = 1)
if ($null -ne $RequireFast -and $RequireFast.RequireFast -eq 1) {
    Write-Host "[+] Strict Kerberos Armoring enforcement is ENABLED (RequireFast = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Strict Kerberos Armoring enforcement is NOT configured (RequireFast != 1)." -ForegroundColor Red
    $Vulnerable = $true
}

if ($Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PawKerberosArmoring.ps1
# Description: Configures Kerberos Armoring (FAST) with strict enforcement and certificate device authentication on PAWs.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring (FAST) on PAWs..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}

# 1. Enable Kerberos client support for claims and armoring
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord

# 2. Support device authentication using certificate (Automatic)
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord

# 3. Fail authentication requests when Kerberos armoring is not available (Strict FAST enforcement on Tier 0 PAWs)
Set-ItemProperty -Path $ClientRegPath -Name "RequireFast" -Value 1 -Type DWord

Write-Host "PAW Kerberos Armoring configured successfully with strict enforcement (RequireFast = 1)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7167" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-168" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-168] Administrative Templates: Disable SMBv1 Protocol Components for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-179](../../08-endpoints/admin-templates/configure-end-at-smbv1.md); for Domain Controllers, refer to [REQ-DC-016](../../02-domain-controllers/disable-smbv1.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-smbv1.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the sensitive administrative bridge between Tier 0 operators and Tier 0 Active Directory Domain Controllers. Any security compromise of a PAW results in complete loss of forest integrity. Legacy Server Message Block version 1 (SMBv1) introduces catastrophic architectural vulnerabilities that cannot be permitted on privileged hardware.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Lanman Workstation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure SMB v1 client driver</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set <xhtml:strong>Driver state</xhtml:strong> drop-down to: <xhtml:code>Disable driver (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Lanman Server</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure SMB v1 server</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtSmbv1.ps1">Download Script: Configure-PawAtSmbv1.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtSmbv1.ps1
# Description: Configures Administrative Templates: Disable SMBv1 Protocol Components for PAWs.

Write-Host "Configuring Administrative Templates: Disable SMBv1 Protocol Components for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10" -Name "Start" -Value 4 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "SMB1" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable SMBv1 Protocol Components for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtSmbv1Status.ps1">Download Script: Get-PawAtSmbv1Status.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtSmbv1Status.ps1
# Description: Audits Administrative Templates: Disable SMBv1 Protocol Components for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable SMBv1 Protocol Components for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10"
$ValueName = "Start"
$ExpectedValue = 4
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$ValueName = "SMB1"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7168" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-169" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-169] Administrative Templates: Configure NetBT Node Type and Name Release for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-180](../../08-endpoints/admin-templates/configure-end-at-netbt-nodetype.md); for Domain Controllers, refer to [REQ-DC-017](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-netbt-nodetype.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are high-value targets operating within dedicated administrative management zones. Permitting unauthenticated broadcast resolution protocols on a PAW introduces critical risks of credential relay and network-level denial of service.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\TCPIP Settings\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>NetBT NodeType configuration</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set <xhtml:strong>NetBT NodeType</xhtml:strong> drop-down to: <xhtml:code>P-node (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtNetbtNodetype.ps1">Download Script: Configure-PawAtNetbtNodetype.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtNetbtNodetype.ps1
# Description: Configures Administrative Templates: Configure NetBT Node Type and Name Release for PAWs.

Write-Host "Configuring Administrative Templates: Configure NetBT Node Type and Name Release for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Name "NodeType" -Value 2 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure NetBT Node Type and Name Release for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtNetbtNodetypeStatus.ps1">Download Script: Get-PawAtNetbtNodetypeStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtNetbtNodetypeStatus.ps1
# Description: Audits Administrative Templates: Configure NetBT Node Type and Name Release for PAWs.

Write-Host "--- Auditing Administrative Templates: Configure NetBT Node Type and Name Release for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters"
$ValueName = "NodeType"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters"
$ValueName = "NoNameReleaseOnDemand"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7169" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-170" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-170] Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-181](../../08-endpoints/admin-templates/configure-end-at-mss-ip-source-routing.md); for Domain Controllers, refer to [REQ-DC-018](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-mss-ip-source-routing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) establish highly privileged administrative sessions (including Kerberos-authenticated WinRM, Remote Desktop with Restricted Admin mode, and LDAP over TLS) to Tier 0 infrastructure. Preserving absolute network routing integrity is critical to prevent traffic interception or session manipulation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (DisableIPSourceRouting IPv6) IP source routing protection level</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Highest protection, source routing is completely disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (DisableIPSourceRouting) IP source routing protection level</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Highest protection, source routing is completely disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtMssIpSourceRouting.ps1">Download Script: Configure-PawAtMssIpSourceRouting.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtMssIpSourceRouting.ps1
# Description: Configures Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs.

Write-Host "Configuring Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Name "DisableIPSourceRouting" -Value 2 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "DisableIPSourceRouting" -Value 2 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "EnableICMPRedirect" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtMssIpSourceRoutingStatus.ps1">Download Script: Get-PawAtMssIpSourceRoutingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtMssIpSourceRoutingStatus.ps1
# Description: Audits Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs.

Write-Host "--- Auditing Administrative Templates: MSS IP Source Routing and ICMP Redirects for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
$ValueName = "DisableIPSourceRouting"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ValueName = "DisableIPSourceRouting"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ValueName = "EnableICMPRedirect"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7170" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-171" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-171] Administrative Templates: MSS System and Session Security Protections for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-mss-system-protections.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are hardened bastion hosts utilized by directory administrators to manage Active Directory domain controllers, Kerberos policies, and enterprise identity databases. Because PAWs operate under maximum privilege conditions, fundamental session security, DLL loading mechanisms, physical console timeouts, and security audit log thresholds must be enforced with zero tolerance for compromise.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following MSS policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (AutoAdminLogon) Enable Automatic Logon</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (SafeDllSearchMode) Enable Safe DLL search mode</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires</xhtml:em>*: Set to <xhtml:code>Enabled: 5 or fewer seconds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning</xhtml:em>*: Set to <xhtml:code>Enabled: 90% or less</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtMssSystemProtections.ps1">Download Script: Configure-PawAtMssSystemProtections.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtMssSystemProtections.ps1
# Description: Configures Administrative Templates: MSS System and Session Security Protections for PAWs.

Write-Host "Configuring Administrative Templates: MSS System and Session Security Protections for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoAdminLogon" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "ScreenSaverGracePeriod" -Value 5 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "SafeDllSearchMode" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security" -Name "WarningLevel" -Value 90 -Type DWord -Force

Write-Host "[+] Administrative Templates: MSS System and Session Security Protections for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtMssSystemProtectionsStatus.ps1">Download Script: Get-PawAtMssSystemProtectionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtMssSystemProtectionsStatus.ps1
# Description: Audits Administrative Templates: MSS System and Session Security Protections for PAWs.

Write-Host "--- Auditing Administrative Templates: MSS System and Session Security Protections for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$ValueName = "AutoAdminLogon"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$ValueName = "ScreenSaverGracePeriod"
$ExpectedValue = 5
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "SafeDllSearchMode"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security"
$ValueName = "WarningLevel"
$ExpectedValue = 90
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v ScreenSaverGracePeriod reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v SafeDllSearchMode reg query "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Security" /v WarningLevel </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text AutoAdminLogon            REG_SZ       0 ScreenSaverGracePeriod    REG_DWORD    0x5 SafeDllSearchMode         REG_DWORD    0x1 WarningLevel              REG_DWORD    0x5a </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7171" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-172" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-172] Administrative Templates: Prevent Device Metadata Retrieval from Network for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-device-metadata.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) host high-privilege administrative sessions where access to Active Directory domain controllers, PKI certificate authorities, and Tier 0 identity assets is executed. Hardware peripherals utilized on PAWs are strictly constrained to high-assurance authentication devices, such as smart card readers, cryptographic hardware security keys (FIDO2/YubiKeys), and dedicated administrative input hardware.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Device Installation</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Prevent device metadata retrieval from the Internet</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtDeviceMetadata.ps1">Download Script: Configure-PawAtDeviceMetadata.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtDeviceMetadata.ps1
# Description: Configures Administrative Templates: Prevent Device Metadata Retrieval from Network for PAWs.

Write-Host "Configuring Administrative Templates: Prevent Device Metadata Retrieval from Network for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Prevent Device Metadata Retrieval from Network applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtDeviceMetadataStatus.ps1">Download Script: Get-PawAtDeviceMetadataStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtDeviceMetadataStatus.ps1
# Description: Audits Administrative Templates: Prevent Device Metadata Retrieval from Network for PAWs.

Write-Host "--- Auditing Administrative Templates: Prevent Device Metadata Retrieval from Network ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata"
$ValueName = "PreventDeviceMetadataFromNetwork"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v PreventDeviceMetadataFromNetwork </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text PreventDeviceMetadataFromNetwork    REG_DWORD    0x1 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7172" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-173" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-173] Administrative Templates: Enforce Group Policy Background Processing for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-gp-processing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are high-security administrative bastion hosts dedicated exclusively to Tier 0 directory services management. Maintaining a deterministic, tamper-resistant system state on PAWs is a foundational requirement of the Microsoft Clean Source and tiering security models.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Group Policy</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure registry policy processing</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Uncheck </xhtml:em>
            <xhtml:em>Do not apply during periodic background processing</xhtml:em>*.</xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure security policy processing</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Uncheck </xhtml:em>
            <xhtml:em>Do not apply during periodic background processing</xhtml:em>*.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for both policies.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtGpProcessing.ps1">Download Script: Configure-PawAtGpProcessing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtGpProcessing.ps1
# Description: Configures Administrative Templates: Enforce Group Policy Background Processing for PAWs.

Write-Host "Configuring Administrative Templates: Enforce Group Policy Background Processing for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Name "NoBackgroundPolicy" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Name "NoGPOListChanges" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Name "NoBackgroundPolicy" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Name "NoGPOListChanges" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Enforce Group Policy Background Processing for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtGpProcessingStatus.ps1">Download Script: Get-PawAtGpProcessingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtGpProcessingStatus.ps1
# Description: Audits Administrative Templates: Enforce Group Policy Background Processing for PAWs.

Write-Host "--- Auditing Administrative Templates: Enforce Group Policy Background Processing for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}"
$ValueName = "NoBackgroundPolicy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}"
$ValueName = "NoGPOListChanges"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
$ValueName = "NoBackgroundPolicy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
$ValueName = "NoGPOListChanges"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" /s </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>NoBackgroundPolicy</xhtml:code> and <xhtml:code>NoGPOListChanges</xhtml:code> are present and set to <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7173" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-174" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-174] Administrative Templates: Disable Cross-Device Experiences for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-cross-device-experiences.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) provide a dedicated, isolated execution environment for managing Tier 0 Active Directory Domain Services, Public Key Infrastructure (PKI), and critical identity systems. The Windows Connected Devices Platform (CDP / Project Rome) introduces capabilities—such as cross-device task roaming, shared activity feeds, and cloud-synchronized clipboard buffers—that are fundamentally incompatible with the strict tiering and isolation guarantees required on a PAW.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Cross-Device Experiences</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Continue experiences on this device</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtCrossDeviceExperiences.ps1">Download Script: Configure-PawAtCrossDeviceExperiences.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtCrossDeviceExperiences.ps1
# Description: Configures Administrative Templates: Disable Cross-Device Experiences for PAWs.

Write-Host "Configuring Administrative Templates: Disable Cross-Device Experiences for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableCdp" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Cross-Device Experiences for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtCrossDeviceExperiencesStatus.ps1">Download Script: Get-PawAtCrossDeviceExperiencesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtCrossDeviceExperiencesStatus.ps1
# Description: Audits Administrative Templates: Disable Cross-Device Experiences for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Cross-Device Experiences for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "EnableCdp"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v EnableCdp </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text EnableCdp    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7174" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-175" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-175] Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-186](../../08-endpoints/admin-templates/configure-end-at-internet-communication.md); for Domain Controllers, refer to [REQ-DC-027](../../02-domain-controllers/configure-telemetry-privacy.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-internet-communication.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) reside in isolated administrative zones dedicated to the management of Active Directory Domain Controllers and enterprise tier-0 identity infrastructure. Automated internet communication channels, web wizard downloads, and dynamic HTTP driver retrieval represent intolerable attack surfaces on privileged hosts.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off downloading of print drivers over HTTP</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off Internet download for Web publishing and online ordering wizards</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtInternetCommunication.ps1">Download Script: Configure-PawAtInternetCommunication.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtInternetCommunication.ps1
# Description: Configures Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs.

Write-Host "Configuring Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" -Name "DisableWebPnPDownload" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoWebServices" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtInternetCommunicationStatus.ps1">Download Script: Get-PawAtInternetCommunicationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtInternetCommunicationStatus.ps1
# Description: Audits Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs.

Write-Host "--- Auditing Administrative Templates: Restrict Internet Communication and Web Downloads for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
$ValueName = "DisableWebPnPDownload"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$ValueName = "NoWebServices"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7175" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-176" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-176] Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-187](../../08-endpoints/admin-templates/configure-end-at-lsa-custom-ssps.md); for complementary LSA Protection, refer to [REQ-PAW-007](../../07-paws/enable-lsa-protection.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1903+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-lsa-custom-ssps.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) operate in the Tier 0 administrative plane, handling Kerberos Ticket Granting Tickets (TGTs), Smart Card PINs, and administrative authentication tokens for Active Directory Domain Controllers. Protecting the Local Security Authority Subsystem Service (<xhtml:code>lsass.exe</xhtml:code>) against DLL injection and persistence is a vital baseline defense.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Local Security Authority</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow Custom SSPs and APs to be loaded into LSASS</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtLsaCustomSsps.ps1">Download Script: Configure-PawAtLsaCustomSsps.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtLsaCustomSsps.ps1
# Description: Configures Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs.

Write-Host "Configuring Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowCustomSSPsAPs" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtLsaCustomSspsStatus.ps1">Download Script: Get-PawAtLsaCustomSspsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtLsaCustomSspsStatus.ps1
# Description: Audits Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs.

Write-Host "--- Auditing Administrative Templates: Block Custom SSPs and APs from Loading into LSASS for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "AllowCustomSSPsAPs"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7176" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-177" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-177] Administrative Templates: Logon Display and Credential Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-188](../../08-endpoints/admin-templates/configure-end-at-logon-display-options.md); for Domain Controllers, refer to [REQ-DC-024](../../02-domain-controllers/configure-security-options.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-logon-display-options.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated management perimeter for Active Directory Domain Controllers and enterprise tier-0 administrative roles. Visual information disclosure, network re-association controls at lock screen, and consumer authentication features introduce critical exposure to administrative credential theft and physical exploitation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Logon</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Block user from showing account details on sign-in</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not display network selection UI</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not enumerate connected users on domain-joined computers</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off app notifications on the lock screen</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off picture password sign-in</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn on convenience PIN sign-in</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent the use of security questions for local accounts</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure the transmission of the user's password in the content of MPR notifications sent by winlogon</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtLogonDisplayOptions.ps1">Download Script: Configure-PawAtLogonDisplayOptions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtLogonDisplayOptions.ps1
# Description: Configures Administrative Templates: Logon Display and Credential Restrictions for PAWs.

Write-Host "Configuring Administrative Templates: Logon Display and Credential Restrictions for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "BlockUserFromShowingAccountDetailsOnSignin" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DontDisplayNetworkSelectionUI" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DontEnumerateConnectedUsers" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DisableLockScreenAppNotifications" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "BlockDomainPicturePassword" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowDomainPINLogon" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "NoLocalPasswordResetQuestions" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableMPR" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Logon Display and Credential Restrictions for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtLogonDisplayOptionsStatus.ps1">Download Script: Get-PawAtLogonDisplayOptionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtLogonDisplayOptionsStatus.ps1
# Description: Audits Administrative Templates: Logon Display and Credential Restrictions for PAWs.

Write-Host "--- Auditing Administrative Templates: Logon Display and Credential Restrictions for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "BlockUserFromShowingAccountDetailsOnSignin"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DontDisplayNetworkSelectionUI"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DontEnumerateConnectedUsers"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DisableLockScreenAppNotifications"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "BlockDomainPicturePassword"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "AllowDomainPINLogon"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "NoLocalPasswordResetQuestions"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "EnableMPR"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7177" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-178" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-178] Administrative Templates: Disable Connected Standby Network Connectivity for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-power-connected-standby.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are high-assurance hardware platforms dedicated exclusively to Tier 0 directory administration. Modern laptop hardware supporting Modern Standby (S0 Low Power Idle) allows network adapters (Wi-Fi, Ethernet, cellular) to maintain active IP stacks and receive incoming network frames while the machine is sleeping or the lid is closed. Allowing unattended network activity on a PAW directly violates Tier 0 physical and network isolation standards.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Power Management\Sleep Settings</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow network connectivity during connected-standby (on battery)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow network connectivity during connected-standby (plugged in)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for both policies.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtPowerConnectedStandby.ps1">Download Script: Configure-PawAtPowerConnectedStandby.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtPowerConnectedStandby.ps1
# Description: Configures Administrative Templates: Disable Connected Standby Network Connectivity for PAWs.

Write-Host "Configuring Administrative Templates: Disable Connected Standby Network Connectivity for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Name "DCSettingIndex" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Name "ACSettingIndex" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Connected Standby Network Connectivity for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtPowerConnectedStandbyStatus.ps1">Download Script: Get-PawAtPowerConnectedStandbyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtPowerConnectedStandbyStatus.ps1
# Description: Audits Administrative Templates: Disable Connected Standby Network Connectivity for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Connected Standby Network Connectivity for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9"
$ValueName = "DCSettingIndex"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9"
$ValueName = "ACSettingIndex"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" /s </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text DCSettingIndex    REG_DWORD    0x0 ACSettingIndex    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7178" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-179" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-179] Administrative Templates: Disable Remote Assistance for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-remote-assistance.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to managing Tier 0 Active Directory Domain Services, root certificate authorities, and core directory security infrastructure. Permitting any form of Remote Assistance on a PAW constitutes an intolerable security architecture violation that shatters Active Directory administrative tiering.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Remote Assistance</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure Offer Remote Assistance</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtRemoteAssistance.ps1">Download Script: Configure-PawAtRemoteAssistance.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtRemoteAssistance.ps1
# Description: Configures Administrative Templates: Disable Remote Assistance for PAWs.

Write-Host "Configuring Administrative Templates: Disable Remote Assistance for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "fAllowUnsolicited" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Remote Assistance for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtRemoteAssistanceStatus.ps1">Download Script: Get-PawAtRemoteAssistanceStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtRemoteAssistanceStatus.ps1
# Description: Audits Administrative Templates: Disable Remote Assistance for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Remote Assistance for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
$ValueName = "fAllowUnsolicited"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fAllowUnsolicited </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text fAllowUnsolicited    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7179" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-180" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-180] Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-191](../../08-endpoints/admin-templates/configure-end-at-rpc-endpoint-mapper-auth.md); for Domain Controllers, refer to [REQ-DC-018](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-rpc-endpoint-mapper-auth.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) execute high-privilege Remote Procedure Call (RPC) routines when administering Domain Controllers, certificate authorities, and directory services. Hardening the RPC resolution mechanism is essential to protect administrative credentials and prevent malicious traffic redirection.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Remote Procedure Call</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable RPC Endpoint Mapper Client Authentication</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtRpcEndpointMapperAuth.ps1">Download Script: Configure-PawAtRpcEndpointMapperAuth.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtRpcEndpointMapperAuth.ps1
# Description: Configures Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs.

Write-Host "Configuring Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" -Name "EnableAuthEpResolution" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtRpcEndpointMapperAuthStatus.ps1">Download Script: Get-PawAtRpcEndpointMapperAuthStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtRpcEndpointMapperAuthStatus.ps1
# Description: Audits Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs.

Write-Host "--- Auditing Administrative Templates: Enable RPC Endpoint Mapper Client Authentication for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc"
$ValueName = "EnableAuthEpResolution"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7180" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-181" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-181] Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-192](../../08-endpoints/admin-templates/configure-end-at-w32time-ntp-client.md); for Domain Controllers, refer to [REQ-DC-020](../../02-domain-controllers/configure-pdc-time-sync.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-w32time-ntp-client.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) perform high-consequence administrative operations across Tier 0 infrastructure. Precise timekeeping is a non-negotiable prerequisite for Kerberos ticket validation, security event audit sequencing, and cryptographic certificate verification.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service\Time Providers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable Windows NTP Client</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service\Time Providers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable Windows NTP Server</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtW32timeNtpClient.ps1">Download Script: Configure-PawAtW32timeNtpClient.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtW32timeNtpClient.ps1
# Description: Configures Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs.

Write-Host "Configuring Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" -Name "Enabled" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" -Name "Enabled" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtW32timeNtpClientStatus.ps1">Download Script: Get-PawAtW32timeNtpClientStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtW32timeNtpClientStatus.ps1
# Description: Audits Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs.

Write-Host "--- Auditing Administrative Templates: Configure Windows Time Service NTP Client and Server for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient"
$ValueName = "Enabled"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer"
$ValueName = "Enabled"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7181" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-182" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-182] Administrative Templates: App Package Deployment Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-193](../../08-endpoints/admin-templates/configure-end-at-appx-deployment-restrictions.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-appx-deployment-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to directory administration and Tier 0 infrastructure management. Application installation on a PAW must adhere to the strictest change management, code signing, and administrative boundaries.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Package Deployment</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Not allow per-user unsigned packages to install by default (requires explicitly allow per install)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Package Deployment</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent non-admin users from installing packaged Windows apps</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtAppxDeploymentRestrictions.ps1">Download Script: Configure-PawAtAppxDeploymentRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtAppxDeploymentRestrictions.ps1
# Description: Configures Administrative Templates: App Package Deployment Restrictions for PAWs.

Write-Host "Configuring Administrative Templates: App Package Deployment Restrictions for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Name "DisablePerUserUnsignedPackagesByDefault" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Name "BlockNonAdminUserInstall" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: App Package Deployment Restrictions for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtAppxDeploymentRestrictionsStatus.ps1">Download Script: Get-PawAtAppxDeploymentRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtAppxDeploymentRestrictionsStatus.ps1
# Description: Audits Administrative Templates: App Package Deployment Restrictions for PAWs.

Write-Host "--- Auditing Administrative Templates: App Package Deployment Restrictions for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx"
$ValueName = "DisablePerUserUnsignedPackagesByDefault"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx"
$ValueName = "BlockNonAdminUserInstall"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7182" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-183" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-183] Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-194](../../08-endpoints/admin-templates/configure-end-at-biometrics-anti-spoofing.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-biometrics-anti-spoofing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the highest-trust endpoints within an Active Directory enterprise architecture. Physical access to an unlocked PAW grants direct compromise capability over Tier 0 directory services. If biometric facial verification is utilized for PAW operator logon, it must enforce the highest cryptographic and hardware liveness guarantees.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Biometrics\Facial Features</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure enhanced anti-spoofing</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtBiometricsAntiSpoofing.ps1">Download Script: Configure-PawAtBiometricsAntiSpoofing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtBiometricsAntiSpoofing.ps1
# Description: Configures Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs.

Write-Host "Configuring Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" -Name "EnhancedAntiSpoofing" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtBiometricsAntiSpoofingStatus.ps1">Download Script: Get-PawAtBiometricsAntiSpoofingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtBiometricsAntiSpoofingStatus.ps1
# Description: Audits Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs.

Write-Host "--- Auditing Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures"
$ValueName = "EnhancedAntiSpoofing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7183" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-184" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-184] Administrative Templates: Disable Cloud Consumer Account State Content for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-cloud-consumer-content.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated, single-purpose endpoints reserved exclusively for Tier 0 Active Directory and infrastructure administration. Windows consumer-oriented shell enhancements—such as promotional subscription cards, consumer OneDrive prompts, and personal Microsoft Account (MSA) suggestions—introduce severe architectural and operational risks to high-assurance administrative hosts.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Cloud Content</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Turn off cloud consumer account state content</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and initiate policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtCloudConsumerContent.ps1">Download Script: Configure-PawAtCloudConsumerContent.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtCloudConsumerContent.ps1
# Description: Configures Administrative Templates: Disable Cloud Consumer Account State Content for PAWs.

Write-Host "Configuring Administrative Templates: Disable Cloud Consumer Account State Content for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableConsumerAccountStateContent" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Cloud Consumer Account State Content for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtCloudConsumerContentStatus.ps1">Download Script: Get-PawAtCloudConsumerContentStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtCloudConsumerContentStatus.ps1
# Description: Audits Administrative Templates: Disable Cloud Consumer Account State Content for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Cloud Consumer Account State Content for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent"
$ValueName = "DisableConsumerAccountStateContent"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableConsumerAccountStateContent </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text DisableConsumerAccountStateContent    REG_DWORD    0x1 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7184" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-185" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-185] Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-196](../../08-endpoints/admin-templates/configure-end-at-connect-pin-pairing.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-connect-pin-pairing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) operate within dedicated administrative perimeters for Tier 0 Active Directory management. Wireless projection capabilities (Miracast over Wi-Fi Direct) introduce serious risks of over-the-air hijacking and unauthenticated input injection if not strictly hardened.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Connect</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Require pin for pairing</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Always</xhtml:code> (or <xhtml:code>First Time</xhtml:code>)</xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtConnectPinPairing.ps1">Download Script: Configure-PawAtConnectPinPairing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtConnectPinPairing.ps1
# Description: Configures Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs.

Write-Host "Configuring Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect" -Name "RequirePinForPairing" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtConnectPinPairingStatus.ps1">Download Script: Get-PawAtConnectPinPairingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtConnectPinPairingStatus.ps1
# Description: Audits Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs.

Write-Host "--- Auditing Administrative Templates: Require PIN for Connect Wireless Pairing for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect"
$ValueName = "RequirePinForPairing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7185" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-186" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-186] Administrative Templates: Credential User Interface Security Protections for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-197](../../08-endpoints/admin-templates/configure-end-at-credui-protections.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-credui-protections.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to high-privilege Tier 0 Active Directory management tasks. Credential collection interfaces must maintain maximum visual confidentiality and prevent information disclosure regarding administrative identities.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Credential User Interface</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not display the password reveal button</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Credential User Interface</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enumerate administrator accounts on elevation</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtCreduiProtections.ps1">Download Script: Configure-PawAtCreduiProtections.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtCreduiProtections.ps1
# Description: Configures Administrative Templates: Credential User Interface Security Protections for PAWs.

Write-Host "Configuring Administrative Templates: Credential User Interface Security Protections for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI" -Name "DisablePasswordReveal" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" -Name "EnumerateAdministrators" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Credential User Interface Security Protections for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtCreduiProtectionsStatus.ps1">Download Script: Get-PawAtCreduiProtectionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtCreduiProtectionsStatus.ps1
# Description: Audits Administrative Templates: Credential User Interface Security Protections for PAWs.

Write-Host "--- Auditing Administrative Templates: Credential User Interface Security Protections for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI"
$ValueName = "DisablePasswordReveal"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI"
$ValueName = "EnumerateAdministrators"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7186" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-187" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-187] Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-data-collection-preview-builds.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are the dedicated administrative bastion hosts for Tier 0 Active Directory Domain Services, enterprise root certification authorities, and identity synchronization infrastructure. Workstations in this tier manage unconstrained directory objects, Kerberos Ticket Granting Service (TGS) sessions, and domain administrator secrets. The default Windows diagnostic telemetry, crash reporting, and preview build mechanisms pose catastrophic security risks to high-assurance Tier 0 environments.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Data Collection and Preview Builds</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Disable OneSettings Downloads</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Do not show feedback notifications</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enable OneSettings Auditing</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Limit Diagnostic Log Collection</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Limit Dump Collection</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Toggle user control over Insider builds</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtDataCollectionPreviewBuilds.ps1">Download Script: Configure-PawAtDataCollectionPreviewBuilds.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtDataCollectionPreviewBuilds.ps1
# Description: Configures Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs.

Write-Host "Configuring Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DisableOneSettingsDownloads" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DoNotShowFeedbackNotifications" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "EnableOneSettingsAuditing" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "LimitDiagnosticLogCollection" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "LimitDumpCollection" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" -Name "AllowBuildPreview" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtDataCollectionPreviewBuildsStatus.ps1">Download Script: Get-PawAtDataCollectionPreviewBuildsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtDataCollectionPreviewBuildsStatus.ps1
# Description: Audits Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs.

Write-Host "--- Auditing Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "DisableOneSettingsDownloads"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "DoNotShowFeedbackNotifications"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "EnableOneSettingsAuditing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "LimitDiagnosticLogCollection"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "LimitDumpCollection"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds"
$ValueName = "AllowBuildPreview"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v AllowBuildPreview </xhtml:code>
          <xhtml:code /> Verify the expected DWORD values: <xhtml:code />
          <xhtml:code>text DisableOneSettingsDownloads     REG_DWORD    0x1 DoNotShowFeedbackNotifications  REG_DWORD    0x1 EnableOneSettingsAuditing       REG_DWORD    0x1 LimitDiagnosticLogCollection    REG_DWORD    0x1 LimitDumpCollection             REG_DWORD    0x1 AllowBuildPreview               REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7187" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-188" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-188] Administrative Templates: App Installer Protocol and Execution Controls for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-199](../../08-endpoints/admin-templates/configure-end-at-app-installer-controls.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1709+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-app-installer-controls.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated platform for Tier 0 Active Directory operations. Protecting the workstation from remote initial access vectors is paramount. The Windows App Installer protocol and package execution mechanisms present a severe vector for untrusted payload delivery that must be comprehensively disabled.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Installer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer ms-appinstaller protocol</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Experimental Features</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Hash Override</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Local Archive Malware Scan Override</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Microsoft Store Source Certificate Validation Bypass</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtAppInstallerControls.ps1">Download Script: Configure-PawAtAppInstallerControls.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtAppInstallerControls.ps1
# Description: Configures Administrative Templates: App Installer Protocol and Execution Controls for PAWs.

Write-Host "Configuring Administrative Templates: App Installer Protocol and Execution Controls for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableExperimentalFeatures" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableHashOverride" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableLocalArchiveMalwareScanOverride" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableBypassCertificatePinningForMicrosoftStore" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableMSAppInstallerProtocol" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: App Installer Protocol and Execution Controls for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtAppInstallerControlsStatus.ps1">Download Script: Get-PawAtAppInstallerControlsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtAppInstallerControlsStatus.ps1
# Description: Audits Administrative Templates: App Installer Protocol and Execution Controls for PAWs.

Write-Host "--- Auditing Administrative Templates: App Installer Protocol and Execution Controls for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableExperimentalFeatures"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableHashOverride"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableLocalArchiveMalwareScanOverride"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableBypassCertificatePinningForMicrosoftStore"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableMSAppInstallerProtocol"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7188" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-189" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-189] Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-event-log-sizes.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated management plane for Active Directory Domain Controllers, Tier 0 directory services, and critical identity infrastructure. Every interactive logon, administrative command execution, PowerShell script block, and remote management session initiated from a PAW carries severe security sensitivity.</xhtml:p>
        <xhtml:p>Default event log capacities (20 MB) or legacy 192 MB baselines roll over rapidly during heavy administrative activity or forensic investigations, destroying vital attribution evidence. Expanding the <xhtml:strong>Security</xhtml:strong> log to <xhtml:strong>1 GB</xhtml:strong> (<xhtml:code>1,048,576 KB</xhtml:code>), <xhtml:strong>System</xhtml:strong> and <xhtml:strong>Application</xhtml:strong> logs to <xhtml:strong>128 MB</xhtml:strong> (<xhtml:code>131,072 KB</xhtml:code>), and <xhtml:strong>Setup</xhtml:strong> log to <xhtml:strong>32 MB</xhtml:strong> (<xhtml:code>32,768 KB</xhtml:code>) establishes a robust local forensic buffer that preserves audit trails across extended operational periods:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Application</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>131072</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>1048576</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Setup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>32768</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>131072</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtEventLogSizes.ps1">Download Script: Configure-PawAtEventLogSizes.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtEventLogSizes.ps1
# Description: Configures Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs.

Write-Host "Configuring Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "MaxSize" -Value 131072 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "MaxSize" -Value 1048576 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "MaxSize" -Value 32768 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "MaxSize" -Value 131072 -Type DWord -Force

Write-Host "[+] Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtEventLogSizesStatus.ps1">Download Script: Get-PawAtEventLogSizesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtEventLogSizesStatus.ps1
# Description: Audits Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs.

Write-Host "--- Auditing Administrative Templates: Event Log Maximum File Sizes and Retention Policies for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application"
$ValueName = "MaxSize"
$ExpectedValue = 131072
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security"
$ValueName = "MaxSize"
$ExpectedValue = 1048576
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup"
$ValueName = "MaxSize"
$ExpectedValue = 32768
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System"
$ValueName = "MaxSize"
$ExpectedValue = 131072
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied log configurations via command line using <xhtml:code>wevtutil</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd wevtutil gl Application wevtutil gl Security wevtutil gl Setup wevtutil gl System </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>maxSize</xhtml:code> reflects the configured byte values (<xhtml:code>1073741824</xhtml:code> bytes for Security, <xhtml:code>134217728</xhtml:code> bytes for System/Application, <xhtml:code>33554432</xhtml:code> bytes for Setup) and <xhtml:code>retention</xhtml:code> is set to <xhtml:code>false</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7189" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-190" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-190] Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-201](../../08-endpoints/admin-templates/configure-end-at-file-explorer-motw.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-file-explorer-motw.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) represent Tier 0 administrative boundaries. Protecting these high-value machines against unauthorized code execution requires enforcing all layers of Windows execution policy and download origin tracking.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\File Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not apply the Mark of the Web tag to files copied from insecure sources</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures MotW is applied)</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\File Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off shell protocol protected mode</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures Protected Mode is enforced)</xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtFileExplorerMotw.ps1">Download Script: Configure-PawAtFileExplorerMotw.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtFileExplorerMotw.ps1
# Description: Configures Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs.

Write-Host "Configuring Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "DisableMotWOnInsecurePathCopy" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "PreXPSP2ShellProtocolBehavior" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtFileExplorerMotwStatus.ps1">Download Script: Get-PawAtFileExplorerMotwStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtFileExplorerMotwStatus.ps1
# Description: Audits Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs.

Write-Host "--- Auditing Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
$ValueName = "DisableMotWOnInsecurePathCopy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$ValueName = "PreXPSP2ShellProtocolBehavior"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7190" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-191" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-191] Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-202](../../08-endpoints/admin-templates/configure-end-at-internet-explorer-retirement.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-internet-explorer-retirement.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are hardened environments dedicated to Tier 0 infrastructure management. General web browsing on a PAW is strictly prohibited by design. However, legacy operating system binaries and background feed engines remain embedded in the Windows platform, requiring absolute administrative disabling to prevent exploitation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Internet Explorer 11 as a standalone browser</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Always</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer\Feeds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent downloading of enclosures</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer\Feeds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn on Basic feed authentication over HTTP</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtInternetExplorerRetirement.ps1">Download Script: Configure-PawAtInternetExplorerRetirement.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtInternetExplorerRetirement.ps1
# Description: Configures Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs.

Write-Host "Configuring Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" -Name "NotifyDisableIEOptions" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Name "DisableEnclosureDownload" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Name "AllowBasicAuthInClear" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtInternetExplorerRetirementStatus.ps1">Download Script: Get-PawAtInternetExplorerRetirementStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtInternetExplorerRetirementStatus.ps1
# Description: Audits Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs.

Write-Host "--- Auditing Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main"
$ValueName = "NotifyDisableIEOptions"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds"
$ValueName = "DisableEnclosureDownload"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds"
$ValueName = "AllowBasicAuthInClear"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7191" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-193" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-193] Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-search-cortana-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to Tier 0 Active Directory and core infrastructure administration. Because administrative consoles are used to generate disaster-recovery scripts, inspect Active Directory objects, and manage domain secrets, the operating system search subsystem must be strictly constrained against cryptographic degradation and side-channel leakage.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Search</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Cortana</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Cortana above lock screen</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow indexing of encrypted files</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow search and Cortana to use location</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtSearchCortanaRestrictions.ps1">Download Script: Configure-PawAtSearchCortanaRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtSearchCortanaRestrictions.ps1
# Description: Configures Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs.

Write-Host "Configuring Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowCortana" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowCortanaAboveLock" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowIndexingEncryptedStoresOrItems" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowSearchToUseLocation" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtSearchCortanaRestrictionsStatus.ps1">Download Script: Get-PawAtSearchCortanaRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtSearchCortanaRestrictionsStatus.ps1
# Description: Audits Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs.

Write-Host "--- Auditing Administrative Templates: Windows Search and Cortana Privacy Restrictions for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowCortana"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowCortanaAboveLock"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowIndexingEncryptedStoresOrItems"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowSearchToUseLocation"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /s </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text AllowCortana                          REG_DWORD    0x0 AllowCortanaAboveLock                 REG_DWORD    0x0 AllowIndexingEncryptedStoresOrItems   REG_DWORD    0x0 AllowSearchToUseLocation              REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7193" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-194" severity="medium" weight="10.0" selected="false">
      <title>[REQ-PAW-194] Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-205](../../08-endpoints/admin-templates/configure-end-at-windows-store-restrictions.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-windows-store-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) execute mission-critical directory administration tools. Essential system management utilities (such as Windows Terminal and system runtime dependencies) are maintained through modern packaging pipelines, requiring rigorous patch hygiene without exposing the privileged environment to uncoordinated operating system upgrades.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Store</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off Automatic Download and Install of updates</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures updates are downloaded automatically)</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Store</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off the offer to update to the latest version of Windows</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtWindowsStoreRestrictions.ps1">Download Script: Configure-PawAtWindowsStoreRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtWindowsStoreRestrictions.ps1
# Description: Configures Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs.

Write-Host "Configuring Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Name "AutoDownload" -Value 4 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Name "DisableOSUpgrade" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtWindowsStoreRestrictionsStatus.ps1">Download Script: Get-PawAtWindowsStoreRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtWindowsStoreRestrictionsStatus.ps1
# Description: Audits Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs.

Write-Host "--- Auditing Administrative Templates: Windows Store Updates and OS Upgrade Restrictions for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$ValueName = "AutoDownload"
$ExpectedValue = 4
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$ValueName = "DisableOSUpgrade"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7194" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-195" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-195] Administrative Templates: Disable Windows Widgets and News Feed for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-windows-widgets-dsh.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) provide the highest level of security isolation for Tier 0 Active Directory administration. They operate under a strict "clean source" principle where only vetted administrative binaries and management consoles are permitted to execute. Windows Widgets and News and Interests dynamically embed web rendering runtimes (Microsoft Edge WebView2) into the taskbar shell, directly violating core PAW security architecture.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Widgets</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow widgets</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtWindowsWidgetsDsh.ps1">Download Script: Configure-PawAtWindowsWidgetsDsh.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtWindowsWidgetsDsh.ps1
# Description: Configures Administrative Templates: Disable Windows Widgets and News Feed for PAWs.

Write-Host "Configuring Administrative Templates: Disable Windows Widgets and News Feed for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh" -Name "AllowNewsAndInterests" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Windows Widgets and News Feed for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtWindowsWidgetsDshStatus.ps1">Download Script: Get-PawAtWindowsWidgetsDshStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtWindowsWidgetsDshStatus.ps1
# Description: Audits Administrative Templates: Disable Windows Widgets and News Feed for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Windows Widgets and News Feed for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Dsh"
$ValueName = "AllowNewsAndInterests"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text AllowNewsAndInterests    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7195" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-196" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-196] Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-207](../../08-endpoints/admin-templates/configure-end-at-automatic-restart-signon.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-automatic-restart-signon.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) process the enterprise's most sensitive credentials, including Active Directory Domain Admin tokens, Kerberos krbtgt keys, and enterprise root CA certificates. Permitting any automated, unattended credential persistence across reboots is fundamentally incompatible with Tier 0 security architectures.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Logon Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Sign-in and lock last interactive user automatically after a restart</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtAutomaticRestartSignon.ps1">Download Script: Configure-PawAtAutomaticRestartSignon.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtAutomaticRestartSignon.ps1
# Description: Configures Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs.

Write-Host "Configuring Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableAutomaticRestartSignOn" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtAutomaticRestartSignonStatus.ps1">Download Script: Get-PawAtAutomaticRestartSignonStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtAutomaticRestartSignonStatus.ps1
# Description: Audits Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs.

Write-Host "--- Auditing Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "DisableAutomaticRestartSignOn"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7196" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-197" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-197] Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-208](../../08-endpoints/admin-templates/configure-end-at-windows-sandbox-isolation.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1903+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-windows-sandbox-isolation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) manage the enterprise's most sensitive Tier 0 identity boundaries. While Windows Sandbox allows isolated testing of administrative scripts or packages, running any virtualized container on a PAW without absolute host-isolation controls introduces severe risks to directory security.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Sandbox</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow clipboard sharing with Windows Sandbox</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Sandbox</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow networking in Windows Sandbox</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the PAW Organizational Unit and enforce policy replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtWindowsSandboxIsolation.ps1">Download Script: Configure-PawAtWindowsSandboxIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtWindowsSandboxIsolation.ps1
# Description: Configures Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs.

Write-Host "Configuring Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Name "AllowClipboardRedirection" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Name "AllowNetworking" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtWindowsSandboxIsolationStatus.ps1">Download Script: Get-PawAtWindowsSandboxIsolationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtWindowsSandboxIsolationStatus.ps1
# Description: Audits Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs.

Write-Host "--- Auditing Administrative Templates: Windows Sandbox Clipboard and Network Isolation for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox"
$ValueName = "AllowClipboardRedirection"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox"
$ValueName = "AllowNetworking"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7197" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-198" severity="high" weight="10.0" selected="false">
      <title>[REQ-PAW-198] Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>07-paws/admin-templates/configure-paw-at-windows-update-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Privileged Access Workstations (PAWs) host the most sensitive interactive sessions and management credentials across the entire enterprise directory structure. Because PAWs are high-value targets for sophisticated adversaries seeking lateral movement into Active Directory Domain Controllers, applying cumulative security patches without latency is vital to system survival.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to the PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Remove access to 'Pause updates' feature</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Manage preview builds</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Select when Preview Builds and Feature Updates are received</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, select <xhtml:strong>Semi-Annual Channel</xhtml:strong>, and set deferral to <xhtml:code>180</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Select when Quality Updates are received</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, set deferral to <xhtml:code>0</xhtml:code> days</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Update\Manage end user experience</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure Automatic Updates</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, select option <xhtml:strong>4 - Auto download and schedule the install</xhtml:strong>, set scheduled install day to <xhtml:code>0 - Every day</xhtml:code>, and configure a suitable maintenance hour (e.g., <xhtml:code>03:00</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>No auto-restart with logged on users for scheduled automatic updates installations</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and verify replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-PawAtWindowsUpdatePolicies.ps1">Download Script: Configure-PawAtWindowsUpdatePolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-PawAtWindowsUpdatePolicies.ps1
# Description: Configures Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs.

Write-Host "Configuring Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "SetDisablePauseUXAccess" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ManagePreviewBuildsPolicyValue" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferFeatureUpdates" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferFeatureUpdatesPeriodInDays" -Value 180 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferQualityUpdates" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferQualityUpdatesPeriodInDays" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "ScheduledInstallDay" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-PawAtWindowsUpdatePoliciesStatus.ps1">Download Script: Get-PawAtWindowsUpdatePoliciesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-PawAtWindowsUpdatePoliciesStatus.ps1
# Description: Audits Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs.

Write-Host "--- Auditing Administrative Templates: Windows Update Deferral and Automatic Installation Policies for PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "SetDisablePauseUXAccess"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "ManagePreviewBuildsPolicyValue"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferFeatureUpdates"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferFeatureUpdatesPeriodInDays"
$ExpectedValue = 180
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferQualityUpdates"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferQualityUpdatesPeriodInDays"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$ValueName = "NoAutoRebootWithLoggedOnUsers"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$ValueName = "ScheduledInstallDay"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /s </xhtml:code>
          <xhtml:code /> Verify that all configured values match the defined baseline.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7198" />
      </check>
    </Rule>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_Defender_Antivirus">
      <title>Defender Antivirus</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-057" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-057] Disable Real-Time Monitoring and Behavior Monitoring Override for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/disable-real-time-monitoring-and-behavior-monitoring-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Real-time scanning, behavior monitoring, and script checking are the core dynamic defense mechanisms of Windows Defender. Disabling or bypassing these controls allows malicious scripts, file-based attacks, and unauthorized in-memory activities to execute undetected.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Turn off real-time protection' to 'Disabled'</xhtml:li>
            <xhtml:li>Set 'Turn on behavior monitoring' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Scan all downloaded files and attachments' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on script scanning' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderRtp.ps1">Download Script: Configure-PawDefenderRtp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderRtp.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderRtpStatus.ps1">Download Script: Get-PawDefenderRtpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderRtpStatus.ps1
$Pref = Get-MpPreference
if ($Pref.DisableRealtimeMonitoring -eq $false -and $Pref.DisableBehaviorMonitoring -eq $false -and $Pref.DisableIOAVProtection -eq $false -and $Pref.DisableScriptScanning -eq $false) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderRtp.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7057" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-058" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-058] Configure Potentially Unwanted Applications (PUA) Protection for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-potentially-unwanted-applications-pua-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Potentially Unwanted Applications (PUA) include adware, torrent clients, cryptominers, and system optimizers that increase risk and resource consumption. Forcing PUA blocking stops standard vectors of shadow IT and unauthorized utility tool execution.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure detection for potentially unwanted applications' to 'Enabled'</xhtml:li>
            <xhtml:li>Select 'Block' in the options dropdown list</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderPUA.ps1">Download Script: Configure-PawDefenderPUA.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderPUAStatus.ps1">Download Script: Get-PawDefenderPUAStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderPUAStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -ErrorAction SilentlyContinue
if ($Pref.PUAProtection -eq 1 -or ($Reg -and $Reg.PUAProtection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7058" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-059" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-059] Prevent Local List Merging and Exclusions Configuration for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/prevent-local-list-merging-and-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>If local administrators or compromised administrative accounts can modify Defender exclusions or merge local lists, they can authorize malicious folders or tools. Restricting list configuration to central GPOs ensures consistent security enforcement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure local administrator merge behavior for lists' to 'Disabled'</xhtml:li>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Prevent users from configuring exclusions' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Control whether or not exclusions are visible to Local Admins' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderLocalExclusions.ps1">Download Script: Configure-PawDefenderLocalExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderLocalExclusionsStatus.ps1">Download Script: Get-PawDefenderLocalExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderLocalExclusionsStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableLocalAdminMerge" -ErrorAction SilentlyContinue
$RegHide = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "HideExclusionsFromLocalAdmins" -ErrorAction SilentlyContinue
$RegConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableLocalAdminConfiguration" -ErrorAction SilentlyContinue
if (($Pref.DisableLocalAdminMerge -eq $true -or ($Reg -and $Reg.DisableLocalAdminMerge -eq 1)) -and
    ($RegHide -and $RegHide.HideExclusionsFromLocalAdmins -eq 1) -and
    ($RegConfig -and $RegConfig.DisableLocalAdminConfiguration -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7059" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-060" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-060] Configure Auto Exclusions Configuration for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-auto-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auto Exclusions automatically configure exclusions for known safe system folders or server roles to reduce performance overhead. Enforcing that auto exclusions are not disabled ensures server performance stability and proper system scanning.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Turn off Auto Exclusions' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderAutoExclusions.ps1">Download Script: Configure-PawDefenderAutoExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderAutoExclusionsStatus.ps1">Download Script: Get-PawDefenderAutoExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderAutoExclusionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableAutoExclusions" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.DisableAutoExclusions -eq 0) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7060" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-061" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-061] Enable EDR in Block Mode for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/enable-edr-in-block-mode.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Endpoint Detection and Response (EDR) in Block Mode allows Defender to take remediation actions on malicious artifacts detected by Microsoft Defender for Endpoint even if another non-Microsoft antivirus is primary. This establishes secondary defensive block capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Features</xhtml:li>
            <xhtml:li>Set 'Enable EDR in block mode' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderEdrBlockMode.ps1">Download Script: Configure-PawDefenderEdrBlockMode.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderEdrBlockModeStatus.ps1">Download Script: Get-PawDefenderEdrBlockModeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderEdrBlockModeStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features" -Name "PassiveRemediation" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.PassiveRemediation -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7061" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-062" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-062] Allow Network Protection on Windows Server for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/allow-network-protection-on-windows-server.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Network Protection blocks processes from accessing malicious domains, phishing sites, and host IP ranges. Allowing Network Protection on Windows Server ensures that member servers running server workloads possess the same IP filter protections as client platforms.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Network Protection</xhtml:li>
            <xhtml:li>Set 'This setting controls whether Network Protection is allowed to be configured into block or audit mode on Windows Server' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderNetworkProtectionServer.ps1">Download Script: Configure-PawDefenderNetworkProtectionServer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderNetworkProtectionServerStatus.ps1">Download Script: Get-PawDefenderNetworkProtectionServerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderNetworkProtectionServerStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" -Name "AllowNetworkProtectionOnWinServer" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.AllowNetworkProtectionOnWinServer -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7062" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-063" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-063] Enable File Hash Computation for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/enable-file-hash-computation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Computing cryptographic file hashes allows Defender to pass hashes of scanned files to cloud and SIEM PAW platforms. This enables precise IOC matches, file tracking, and correlation with threat intelligence repositories.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\MpEngine</xhtml:li>
            <xhtml:li>Set 'Enable file hash computation feature' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderFileHash.ps1">Download Script: Configure-PawDefenderFileHash.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderFileHashStatus.ps1">Download Script: Get-PawDefenderFileHashStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderFileHashStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" -Name "EnableFileHashComputation" -ErrorAction SilentlyContinue
if ($Pref.EnableFileHashComputation -eq $true -or ($Reg -and $Reg.EnableFileHashComputation -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7063" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-064" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-064] Configure Network Inspection System (NIS) settings for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-network-inspection-system-nis-settings.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Network Inspection System (NIS) inspects network traffic patterns for known exploits. Converting warning verdicts to block enforces inline blocking of zero-day exploits, while allowing async inspection prevents performance overhead from slowing local network interfaces.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Network Inspection System</xhtml:li>
            <xhtml:li>Set 'Convert warn verdict to block' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on asynchronous inspection' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderNis.ps1">Download Script: Configure-PawDefenderNis.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderNisStatus.ps1">Download Script: Get-PawDefenderNisStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderNisStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "EnableConvertWarnToBlock" -ErrorAction SilentlyContinue
$RegAsync = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "AllowSwitchToAsyncInspection" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.EnableConvertWarnToBlock -eq 1) -and ($RegAsync -and $RegAsync.AllowSwitchToAsyncInspection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7064" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-065" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-065] Configure OOBE Real-Time Protection and Security Intelligence for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-oobe-real-time-protection-and-security-intelligence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling real-time protection and intelligence updates during the Out-of-Box Experience (OOBE) ensures that the system is fully updated and protected before the initial administrative user signs in or connects to enterprise network nodes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Configure real-time protection and Security Intelligence Updates during OOBE' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderOobeRtp.ps1">Download Script: Configure-PawDefenderOobeRtp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderOobeRtpStatus.ps1">Download Script: Get-PawDefenderOobeRtpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderOobeRtpStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "OobeEnableRtpAndSigUpdate" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.OobeEnableRtpAndSigUpdate -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7065" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-066" severity="low" weight="10.0" selected="false">
        <title>[REQ-PAW-066] Enable Dynamic Signature Dropped Event Reporting for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/enable-dynamic-signature-dropped-event-reporting.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling this log report generation triggers explicit events when a dynamic scan ruleset signature is dropped. This ensures SIEM integrations can immediately log changes in the local threat signatures dataset.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Reporting</xhtml:li>
            <xhtml:li>Set 'Configure whether to report Dynamic Signature dropped events' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderDynamicReporting.ps1">Download Script: Configure-PawDefenderDynamicReporting.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderDynamicReportingStatus.ps1">Download Script: Get-PawDefenderDynamicReportingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderDynamicReportingStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" -Name "EnableDynamicSignatureDroppedEventReporting" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.EnableDynamicSignatureDroppedEventReporting -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7066" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-067" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-067] Configure Quick Scan and Scanning Exclusions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-quick-scan-and-scanning-exclusions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Malware frequently tries to establish persistence in excluded directories or inside packed/compressed executables. Forcing quick scans to include excluded files and ensuring packed file structures are recursively scanned prevents malware evasion.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Scan excluded files and directories during quick scans' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn off scanning of packed executables' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderQuickScan.ps1">Download Script: Configure-PawDefenderQuickScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderQuickScanStatus.ps1">Download Script: Get-PawDefenderQuickScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderQuickScanStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "QuickScanIncludeExclusions" -ErrorAction SilentlyContinue
$RegPack = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DisablePackedExeScanning" -ErrorAction SilentlyContinue
if (($Pref.DisablePackedExeScanning -eq $false -or ($RegPack -and $RegPack.DisablePackedExeScanning -eq 0)) -and
    ($Reg -and $Reg.QuickScanIncludeExclusions -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7067" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-068" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-068] Configure Scheduled Scan Parameters for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-scheduled-scan-parameters.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Ensuring daily scheduled scans, enabling heuristics for behavioral anomaly detection, scan mail attachments, and forcing a catchup scan after at most 7 days ensures system integrity is continually validated.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to run a scheduled scan' to 'Enabled' (Select 'Every day' or '0')</xhtml:li>
            <xhtml:li>Set 'Turn on e-mail scanning' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on heuristics' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Trigger a quick scan after X days without any scans' to 'Enabled' (7 days)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderScheduledScan.ps1">Download Script: Configure-PawDefenderScheduledScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderScheduledScanStatus.ps1">Download Script: Get-PawDefenderScheduledScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderScheduledScanStatus.ps1
$Pref = Get-MpPreference
$RegDays = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DaysWithoutCatchupQuickScan" -ErrorAction SilentlyContinue
if ($Pref.DisableEmailScanning -eq $false -and $Pref.DisableHeuristics -eq $false -and ($RegDays -and $RegDays.DaysWithoutCatchupQuickScan -eq 7)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7068" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-069" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-069] Configure Security Intelligence Update Schedule for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-security-intelligence-update-schedule.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Antivirus signatures must remain fresh to block the latest published threats. Mandating daily checks for updates and marking signatures older than 7 days as out-of-date ensures continuous defense parity.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Security Intelligence Updates</xhtml:li>
            <xhtml:li>Set 'Define the number of days before spyware security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Define the number of days before virus security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to check for security intelligence updates' to 'Enabled' (Every day or 0)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderUpdateSchedule.ps1">Download Script: Configure-PawDefenderUpdateSchedule.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderUpdateScheduleStatus.ps1">Download Script: Get-PawDefenderUpdateScheduleStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderUpdateScheduleStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ASSignatureDue" -ErrorAction SilentlyContinue
$RegAV = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "AVSignatureDue" -ErrorAction SilentlyContinue
$RegDay = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ScheduleDay" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.ASSignatureDue -eq 7) -and ($RegAV -and $RegAV.AVSignatureDue -eq 7) -and ($RegDay -and $RegDay.ScheduleDay -eq 0)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7069" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-071" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-071] Configure Threat Severity Default Quarantine Actions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-threat-severity-default-quarantine-actions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>By default, Defender may prompt users or take actions (like clean/ignore) that leave malware remnants on the filesystem. Configuring default quarantine actions for all severities (low, medium, high, severe) ensures automated containment.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Threats</xhtml:li>
            <xhtml:li>Set 'Specify threat alert levels at which default action should not be taken when detected' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and enter threat levels (1 -&gt; 2, 2 -&gt; 2, 4 -&gt; 2, 5 -&gt; 2)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderThreatActions.ps1">Download Script: Configure-PawDefenderThreatActions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderThreatActionsStatus.ps1">Download Script: Get-PawDefenderThreatActionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderThreatActionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats" -Name "Threats_ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
$RegSev = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.Threats_ThreatSeverityDefaultAction -eq 1) -and 
    ($RegSev -and $RegSev.1 -eq 2 -and $RegSev.2 -eq 2 -and $RegSev.4 -eq 2 -and $RegSev.5 -eq 2)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7071" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-072" severity="low" weight="10.0" selected="false">
        <title>[REQ-PAW-072] Configure Family Options UI Lockdown for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-family-options-ui-lockdown.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Locking down non-essential components of the Windows Security Center interface prevents users from tampering with parental or diagnostic UI controls on enterprise assets.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Family options</xhtml:li>
            <xhtml:li>Set 'Hide the Family options area' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderFamilyLockdown.ps1">Download Script: Configure-PawDefenderFamilyLockdown.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderFamilyLockdownStatus.ps1">Download Script: Get-PawDefenderFamilyLockdownStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderFamilyLockdownStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options" -Name "UILockdown" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.UILockdown -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7072" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-073" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-073] Configure Tamper Protection for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-tamper-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Tamper Protection prevents local administrators or compromised system accounts from disabling Windows Defender services, real-time scanning, or modifying active exclusions locally. This blocks a primary malware persistence vector.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Tamper Protection</xhtml:li>
            <xhtml:li>Set 'Protect Windows Security settings from tampering' to 'Enabled' (Block or On depending on ADMX version)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderTamperProtection.ps1">Download Script: Configure-PawDefenderTamperProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderTamperProtectionStatus.ps1">Download Script: Get-PawDefenderTamperProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderTamperProtectionStatus.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
$TamperVal = Get-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -ErrorAction SilentlyContinue
if ($TamperVal -and $TamperVal.TamperProtection -eq 5) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7073" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-074" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-074] Configure Sandbox Execution Environment for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-sandbox-execution-environment.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Forcing the Windows Defender scanning service (MsMpEng.exe) to run in a restricted AppContainer sandbox prevents privilege escalation. If an attacker exploits a parsing vulnerability in the engine, the compromise is contained inside the sandbox.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Environment</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Environment Variable</xhtml:li>
            <xhtml:li>Configure Action: Update, Type: System, Name: MP_FORCE_USE_SANDBOX, Value: 1</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderSandbox.ps1">Download Script: Configure-PawDefenderSandbox.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderSandboxStatus.ps1">Download Script: Get-PawDefenderSandboxStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderSandboxStatus.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
$SandboxVar = Get-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -ErrorAction SilentlyContinue
if ($SandboxVar -and $SandboxVar.MP_FORCE_USE_SANDBOX -eq "1") {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7074" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-075" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-075] Configure AMSI Authenticode Signature Verification for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-amsi-authenticode-signature-verification.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing signature checks on registered Antimalware Scan Interface (AMSI) providers blocks attackers from registering unsigned rogue AMSI provider DLLs to bypass script analysis.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Registry</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Registry Item</xhtml:li>
            <xhtml:li>Configure Action: Update, Hive: HKEY_LOCAL_MACHINE, Key Path: SOFTWARE\Microsoft\AMSI, Value Name: FeatureBits, Value Type: REG_DWORD, Value Data: 2</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawDefenderAmsiSignature.ps1">Download Script: Configure-PawDefenderAmsiSignature.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawDefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawDefenderAmsiSignatureStatus.ps1">Download Script: Get-PawDefenderAmsiSignatureStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawDefenderAmsiSignatureStatus.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (Test-Path $AmsiPath) {
    $AmsiBits = Get-ItemProperty -Path $AmsiPath -Name "FeatureBits" -ErrorAction SilentlyContinue
    if ($AmsiBits -and $AmsiBits.FeatureBits -eq 2) {
        Write-Output "Compliant"
        exit 0
    }
}
Write-Output "Non-Compliant"
exit 1</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawDefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7075" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-192" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-192] Configure Remote Encryption Protection Mode for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/configure-remote-encryption-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) must maintain the highest standard of endpoint protection against ransomware and lateral movement attempts. Remote Encryption Protection detects and terminates network ransomware attempting to encrypt files over SMB shares. Enforcing Block mode terminates the malicious remote process or network connection attempting rapid or unauthorized file encryption, safeguarding Tier 0 administrative assets from network-based extortion attacks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to PAWs Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Defender Antivirus\Remediation\Behavioral Network Blocks\Brute Force Protection</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Configure Remote Encryption Protection Mode</xhtml:strong>.</xhtml:li>
            <xhtml:li>Set the policy to <xhtml:strong>Enabled</xhtml:strong>, and select <xhtml:strong>Block</xhtml:strong> (value <xhtml:code>2</xhtml:code>) in the dropdown options.</xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify replication.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the Remote Encryption Protection registry value on PAWs:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawRemoteEncryptionProtection.ps1">Download Script: Configure-PawRemoteEncryptionProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawRemoteEncryptionProtection.ps1
# Description: Configures Microsoft Defender Remote Encryption Protection in Block mode on PAWs.

Write-Host "Configuring Microsoft Defender Remote Encryption Protection for PAWs..." -ForegroundColor Cyan

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path -Path $KeyPath)) {
    New-Item -Path $KeyPath -Force | Out-Null
}
Set-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -Value 2 -Type DWord -Force

Write-Host "[+] Remote Encryption Protection applied successfully on PAWs (Block mode)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawRemoteEncryptionProtectionStatus.ps1">Download Script: Get-PawRemoteEncryptionProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawRemoteEncryptionProtectionStatus.ps1
# Description: Audits Microsoft Defender Remote Encryption Protection configuration status on PAWs.

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
$Reg = Get-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -ErrorAction SilentlyContinue

if ($Reg -and $Reg.BruteForceProtectionConfiguredState -eq 2) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawRemoteEncryptionProtection.ps1
# Description: Configures Microsoft Defender Remote Encryption Protection in Block mode on PAWs.

Write-Host "Configuring Microsoft Defender Remote Encryption Protection for PAWs..." -ForegroundColor Cyan

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path -Path $KeyPath)) {
    New-Item -Path $KeyPath -Force | Out-Null
}
Set-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -Value 2 -Type DWord -Force

Write-Host "[+] Remote Encryption Protection applied successfully on PAWs (Block mode)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7192" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_Attack_Surface_Reduction__ASR__Rules">
      <title>Attack Surface Reduction (ASR) Rules</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-076" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-076] ASR: Block abuse of exploited vulnerable signed drivers for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-vulnerable-signed-drivers.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents an application from writing a vulnerable signed driver to disk. Attackers use Bring Your Own Vulnerable Driver (BYOVD) techniques to bypass Windows kernel protections by loading legitimate, signed third-party drivers that contain known vulnerabilities, allowing them to disable security agents and gain kernel-level privileges.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>56a863a9-875e-4185-98a7-b882c64b5ce5</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrVulnerableDrivers.ps1">Download Script: Configure-PawAsrVulnerableDrivers.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrVulnerableDriversStatus.ps1">Download Script: Get-PawAsrVulnerableDriversStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrVulnerableDriversStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -ErrorAction SilentlyContinue
if ($Value -and ($Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq "1" -or $Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7076" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-077" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-077] ASR: Block Adobe Reader from creating child processes for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-adobe-reader-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents Adobe Reader from launching any child processes. Malicious PDF documents frequently attempt to exploit application vulnerabilities or trick users into executing embedded links, which spawns command shells (cmd.exe, powershell.exe) or scripting hosts (wscript.exe) to download and launch secondary malware payloads.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrAdobeChild.ps1">Download Script: Configure-PawAsrAdobeChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrAdobeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrAdobeChildStatus.ps1">Download Script: Get-PawAsrAdobeChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrAdobeChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -ErrorAction SilentlyContinue
if ($Value -and ($Value."7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -eq "1" -or $Value."7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrAdobeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7077" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-078" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-078] ASR: Block all Office applications from creating child processes for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-office-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Office applications (Word, Excel, PowerPoint) from creating child processes. This prevents malicious files containing embedded VBA macros or exploiting unpatched vulnerabilities (such as CVE-2021-40444) from launching scripting environments or system commands to download and execute code.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d4f940ab-401b-4efc-aadc-ad5f3c50688a</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrOfficeChild.ps1">Download Script: Configure-PawAsrOfficeChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrOfficeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrOfficeChildStatus.ps1">Download Script: Get-PawAsrOfficeChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrOfficeChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d4f940ab-401b-4efc-aadc-ad5f3c50688a" -eq "1" -or $Value."d4f940ab-401b-4efc-aadc-ad5f3c50688a" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrOfficeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7078" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-079" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-079] ASR: Block credential stealing from the Windows local security authority subsystem for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-lsass-credential-stealing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks attempts to open or dump the memory of the Local Security Authority Subsystem Service (lsass.exe). Attackers dump LSASS memory using tools like Mimikatz or Task Manager to extract plaintext credentials, Kerberos tickets, or NTLM password hashes from system memory for lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrLsassDump.ps1">Download Script: Configure-PawAsrLsassDump.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrLsassDumpStatus.ps1">Download Script: Get-PawAsrLsassDumpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrLsassDumpStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -ErrorAction SilentlyContinue
if ($Value -and ($Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq "1" -or $Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7079" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-080" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-080] ASR: Block executable content from email client and webmail for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-email-executable-content.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents executable files (such as .exe, .com, .scr, .vbs, .js, or .pif) from launching directly from email clients (like Outlook) or webmail accessed via browser sessions. This stops phishing attacks where users accidentally launch malicious attachments or download payloads directly from web-based email links.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>be9ba2d9-53ea-4cdc-84e5-9b1eeee46550</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrEmailExecutable.ps1">Download Script: Configure-PawAsrEmailExecutable.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrEmailExecutable.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrEmailExecutableStatus.ps1">Download Script: Get-PawAsrEmailExecutableStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrEmailExecutableStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -ErrorAction SilentlyContinue
if ($Value -and ($Value."be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -eq "1" -or $Value."be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrEmailExecutable.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7080" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-081" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-081] ASR: Block executable files from running unless they meet a prevalence, age, or trusted list criterion for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-low-prevalence-executable-files.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks execution of unrecognized, newly compiled, or low-prevalence executable files. This provides initial protection against zero-day malware campaigns and targeted custom payloads that have not yet established reputation telemetry in the Microsoft Cloud Protection network.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>01443614-cd74-433a-b99e-2ecdc07bfc25</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrLowPrevalence.ps1">Download Script: Configure-PawAsrLowPrevalence.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrLowPrevalence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrLowPrevalenceStatus.ps1">Download Script: Get-PawAsrLowPrevalenceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrLowPrevalenceStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -ErrorAction SilentlyContinue
if ($Value -and ($Value."01443614-cd74-433a-b99e-2ecdc07bfc25" -eq "1" -or $Value."01443614-cd74-433a-b99e-2ecdc07bfc25" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrLowPrevalence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7081" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-082" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-082] ASR: Block execution of potentially obfuscated scripts for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-obfuscated-scripts.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks execution of obfuscated or encrypted scripts (such as PowerShell, VBScript, or JavaScript). Threat actors obfuscate their scripts using base64 encoding, custom string manipulation, or encryption to hide the intent of their code and bypass static file scanning and network detection engines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>5beb7efe-fd9a-4556-801d-275e5ffc04cc</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrObfuscatedScripts.ps1">Download Script: Configure-PawAsrObfuscatedScripts.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrObfuscatedScriptsStatus.ps1">Download Script: Get-PawAsrObfuscatedScriptsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrObfuscatedScriptsStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -ErrorAction SilentlyContinue
if ($Value -and ($Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq "1" -or $Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7082" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-083" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-083] ASR: Block JavaScript or VBScript from launching downloaded executable content for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-script-launching-downloaded-content.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents JavaScript or VBScript running locally from launching executable binaries that were downloaded from the internet. Attackers use malicious scripts inside documents or web browsers to download payloads (like ransomware or trojans) to the disk and launch them using local script engines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d3e037e1-3eb8-44c8-a917-57927947596d</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrScriptLaunchExe.ps1">Download Script: Configure-PawAsrScriptLaunchExe.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrScriptLaunchExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrScriptLaunchExeStatus.ps1">Download Script: Get-PawAsrScriptLaunchExeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrScriptLaunchExeStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d3e037e1-3eb8-44c8-a917-57927947596d" -eq "1" -or $Value."d3e037e1-3eb8-44c8-a917-57927947596d" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrScriptLaunchExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7083" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-084" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-084] ASR: Block Office applications from creating executable content for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-office-executable-content-creation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents Microsoft Office applications (Word, Excel, PowerPoint) from creating or writing executable files (e.g., .exe, .dll, .scr) to the local filesystem. Malicious documents often attempt to drop payloads directly into the local temp folders or AppData directories before executing them.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>3b576869-a4ec-4529-8536-b80a7769e899</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrOfficeWriteExe.ps1">Download Script: Configure-PawAsrOfficeWriteExe.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrOfficeWriteExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrOfficeWriteExeStatus.ps1">Download Script: Get-PawAsrOfficeWriteExeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrOfficeWriteExeStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -ErrorAction SilentlyContinue
if ($Value -and ($Value."3b576869-a4ec-4529-8536-b80a7769e899" -eq "1" -or $Value."3b576869-a4ec-4529-8536-b80a7769e899" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrOfficeWriteExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7084" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-085" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-085] ASR: Block Office applications from injecting code into other processes for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-office-code-injection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Office applications from writing code or injecting threads directly into external processes. Threat actors use code injection (such as process hollowing or remote thread creation) inside Office macros to hide execution under clean, trusted system binaries like explorer.exe or svchost.exe.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrOfficeInjection.ps1">Download Script: Configure-PawAsrOfficeInjection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrOfficeInjection.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrOfficeInjectionStatus.ps1">Download Script: Get-PawAsrOfficeInjectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrOfficeInjectionStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -ErrorAction SilentlyContinue
if ($Value -and ($Value."75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -eq "1" -or $Value."75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrOfficeInjection.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7085" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-086" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-086] ASR: Block Office communication application from creating child processes for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-office-communication-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Outlook or other Office communication applications (e.g., Teams, Skype) from creating child processes. This prevents malware payloads delivered through emails, chats, or calendar invites from spawning command-line utilities or scripting environments.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>26190899-1602-49e8-8b27-eb1d0a1ce869</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrOutlookChild.ps1">Download Script: Configure-PawAsrOutlookChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrOutlookChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrOutlookChildStatus.ps1">Download Script: Get-PawAsrOutlookChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrOutlookChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -ErrorAction SilentlyContinue
if ($Value -and ($Value."26190899-1602-49e8-8b27-eb1d0a1ce869" -eq "1" -or $Value."26190899-1602-49e8-8b27-eb1d0a1ce869" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrOutlookChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7086" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-087" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-087] ASR: Block persistence through WMI event subscription for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-wmi-event-subscription-persistence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks threat actors from achieving system persistence by registering permanent Windows Management Instrumentation (WMI) event subscriptions. WMI event subscriptions allow attackers to automatically launch malicious payloads when system triggers occur (like system boot or user logon) without using traditional startup registry keys.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>e6db77e5-3df2-4cf1-b95a-636979351e5b</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrWmiPersistence.ps1">Download Script: Configure-PawAsrWmiPersistence.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrWmiPersistenceStatus.ps1">Download Script: Get-PawAsrWmiPersistenceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrWmiPersistenceStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -ErrorAction SilentlyContinue
if ($Value -and ($Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq "1" -or $Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7087" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-088" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-088] ASR: Block process creations originating from PSExec and WMI commands for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-psexec-wmi-process-creations.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks processes created via WMI commands or PSExec remote execution utilities. This directly stops lateral movement attacks where compromised accounts or threat actors attempt to start commands, backdoors, or credential dumpers remotely across domain-joined servers and PAW platforms.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d1e49aac-8f56-4280-b9ba-993a6d77406c</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrPsexecWmi.ps1">Download Script: Configure-PawAsrPsexecWmi.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrPsexecWmiStatus.ps1">Download Script: Get-PawAsrPsexecWmiStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrPsexecWmiStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq "1" -or $Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7088" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-089" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-089] ASR: Block untrusted and unsigned processes that run from USB for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-unsigned-processes-running-from-usb.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks the execution of unsigned or untrusted processes on removable storage devices (USB drives, external SSDs). This stops physical access vectors, rogue USB drops, and automated worm propagation techniques from running unauthorized installers or scripts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrUsbUnsigned.ps1">Download Script: Configure-PawAsrUsbUnsigned.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrUsbUnsigned.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrUsbUnsignedStatus.ps1">Download Script: Get-PawAsrUsbUnsignedStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrUsbUnsignedStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -ErrorAction SilentlyContinue
if ($Value -and ($Value."b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -eq "1" -or $Value."b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrUsbUnsigned.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7089" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-090" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-090] ASR: Block Win32 API calls from Office macros for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/block-win32-api-calls-from-office-macros.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks VBA macros inside Microsoft Office documents from invoking Win32 API calls. Malicious documents use macros to call kernel memory functions (such as VirtualAlloc, WriteProcessMemory, or CreateThread) to load and execute shellcode in memory without dropping files to disk, bypassing file scanners.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrOfficeWin32Calls.ps1">Download Script: Configure-PawAsrOfficeWin32Calls.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrOfficeWin32Calls.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrOfficeWin32CallsStatus.ps1">Download Script: Get-PawAsrOfficeWin32CallsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrOfficeWin32CallsStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -ErrorAction SilentlyContinue
if ($Value -and ($Value."92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -eq "1" -or $Value."92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrOfficeWin32Calls.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7090" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-091" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-091] ASR: Use advanced protection against ransomware for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/defender/asr/use-advanced-protection-against-ransomware.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enables advanced behavioral heuristics and cloud analytics checks on files that attempt to modify multiple user files, detect signature-less encryption behavior, and block rapid write activity to prevent ransomware from encrypting system and user documents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>c1db55ab-c21a-4637-bb3f-a12568109d35</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-PawAsrRansomware.ps1">Download Script: Configure-PawAsrRansomware.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-PawAsrRansomwareStatus.ps1">Download Script: Get-PawAsrRansomwareStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAsrRansomwareStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -ErrorAction SilentlyContinue
if ($Value -and ($Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq "1" -or $Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7091" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_User_Rights_Assignments">
      <title>User Rights Assignments</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-092" severity="low" weight="10.0" selected="false">
        <title>[REQ-PAW-092] Configure User Rights: Access Credential Manager as a trusted caller for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-096](../../08-endpoints/user-rights/configure-ura-setrustedcredmanaccessprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-setrustedcredmanaccessprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTrustedCredManAccessPrivilege</xhtml:code> allows a process to access the Windows Credential Manager as a trusted caller via internal Credential Manager APIs. The Credential Manager securely stores user domain credentials, web passwords, and certificate secrets used for network authentication.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Access Credential Manager as a trusted caller`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeTrustedCredManAccessPrivilege.ps1">Download Script: Configure-PawUraSeTrustedCredManAccessPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeTrustedCredManAccessPrivilege.ps1
# Configure-PawUraSeTrustedCredManAccessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setrustedcredmanaccessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setrustedcredmanaccessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTrustedCredManAccessPrivilege\s*=") {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTrustedCredManAccessPrivilege = ")
    } else {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeTrustedCredManAccessPrivilegeStatus.ps1">Download Script: Get-PawUraSeTrustedCredManAccessPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeTrustedCredManAccessPrivilegeStatus.ps1
# Get-PawUraSeTrustedCredManAccessPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setrustedcredmanaccessprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTrustedCredManAccessPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeTrustedCredManAccessPrivilege.ps1
# Configure-PawUraSeTrustedCredManAccessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setrustedcredmanaccessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setrustedcredmanaccessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTrustedCredManAccessPrivilege\s*=") {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTrustedCredManAccessPrivilege = ")
    } else {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7092" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-093" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-093] Configure User Rights: Access this computer from the network for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-097](../../08-endpoints/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-104](../../02-domain-controllers/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-senetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeNetworkLogonRight</xhtml:code> determines which security principals are permitted to authenticate and establish network logon sessions (Logon Type 3) across the network over protocols like SMB, RPC, WMI, WinRM, and LDAP. Network logons authenticate users without creating an interactive desktop shell, enabling file share access, remote management, and inter-system synchronization.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Access this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeNetworkLogonRight.ps1">Download Script: Configure-PawUraSeNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeNetworkLogonRight.ps1
# Configure-PawUraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeNetworkLogonRightStatus.ps1">Download Script: Get-PawUraSeNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeNetworkLogonRightStatus.ps1
# Get-PawUraSeNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_senetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeNetworkLogonRight.ps1
# Configure-PawUraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7093" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-094" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-094] Configure User Rights: Act as part of the operating system for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-098](../../08-endpoints/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-105](../../02-domain-controllers/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-setcbprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTcbPrivilege</xhtml:code> identifies its holder as part of the Trusted Computer Base (TCB)—the core inner ring of the operating system. A process possessing this privilege can register as a trusted logon process with the Local Security Authority via <xhtml:code>LsaRegisterLogonProcess</xhtml:code> and invoke <xhtml:code>LsaLogonUser</xhtml:code> to create an arbitrary, fully authenticated access token for any user without knowing the user's password or requiring credentials.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Act as part of the operating system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeTcbPrivilege.ps1">Download Script: Configure-PawUraSeTcbPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeTcbPrivilege.ps1
# Configure-PawUraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeTcbPrivilegeStatus.ps1">Download Script: Get-PawUraSeTcbPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeTcbPrivilegeStatus.ps1
# Get-PawUraSeTcbPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setcbprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTcbPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeTcbPrivilege.ps1
# Configure-PawUraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7094" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-095" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-095] Configure User Rights: Allow log on locally for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-099](../../08-endpoints/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-108](../../02-domain-controllers/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeInteractiveLogonRight</xhtml:code> determines which security principals are permitted to start an interactive logon session (Logon Type 2) at the physical keyboard, display, or virtual machine console. An interactive logon spawns a graphical user shell (<xhtml:code>explorer.exe</xhtml:code>) and interactive desktop session.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Allow log on locally`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeInteractiveLogonRight.ps1">Download Script: Configure-PawUraSeInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeInteractiveLogonRight.ps1
# Configure-PawUraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeInteractiveLogonRightStatus.ps1">Download Script: Get-PawUraSeInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeInteractiveLogonRightStatus.ps1
# Get-PawUraSeInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeInteractiveLogonRight.ps1
# Configure-PawUraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-32-544")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7095" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-096" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-096] Configure User Rights: Back up files and directories for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-100](../../08-endpoints/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-110](../../02-domain-controllers/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sebackupprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeBackupPrivilege</xhtml:code> grants the caller the capability to bypass all read-access security controls (Discretionary Access Control Lists - DACLs) across the entire NTFS filesystem and Windows Registry. When an application opens a file handle specifying the <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> flag in Win32 <xhtml:code>CreateFile</xhtml:code> calls, the Windows kernel I/O manager and Object Manager explicitly bypass standard security descriptor evaluation. This design allows legitimate backup utilities to archive files without requiring explicit read permissions on every individual object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Back up files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeBackupPrivilege.ps1">Download Script: Configure-PawUraSeBackupPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeBackupPrivilege.ps1
# Configure-PawUraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeBackupPrivilegeStatus.ps1">Download Script: Get-PawUraSeBackupPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeBackupPrivilegeStatus.ps1
# Get-PawUraSeBackupPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sebackupprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeBackupPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeBackupPrivilege.ps1
# Configure-PawUraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7096" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-097" severity="low" weight="10.0" selected="false">
        <title>[REQ-PAW-097] Configure User Rights: Create a pagefile for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-103](../../08-endpoints/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-113](../../02-domain-controllers/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-secreatepagefileprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePagefilePrivilege</xhtml:code> allows a process to create, delete, and modify the parameters and allocation sizes of system paging files (<xhtml:code>pagefile.sys</xhtml:code>) via the <xhtml:code>NtCreatePagingFile</xhtml:code> API. The Windows virtual memory manager uses paging files as secondary backing storage for memory pages that are not backed by files. Paging files contain sensitive plaintext data, including process heap allocations, cached authentication tokens, cryptographic keys, and unencrypted file contents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a pagefile`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeCreatePagefilePrivilege.ps1">Download Script: Configure-PawUraSeCreatePagefilePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeCreatePagefilePrivilege.ps1
# Configure-PawUraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeCreatePagefilePrivilegeStatus.ps1">Download Script: Get-PawUraSeCreatePagefilePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeCreatePagefilePrivilegeStatus.ps1
# Get-PawUraSeCreatePagefilePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepagefileprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePagefilePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeCreatePagefilePrivilege.ps1
# Configure-PawUraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7097" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-098" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-098] Configure User Rights: Create a token object for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-104](../../08-endpoints/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-114](../../02-domain-controllers/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-secreatetokenprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateTokenPrivilege</xhtml:code> allows a process to invoke the native API <xhtml:code>NtCreateToken</xhtml:code> to forge an arbitrary Windows primary or impersonation access token from scratch. An access token defines an entity's complete security context, including User SID, Group SIDs, Privileges, Default DACL, Token Type, and Mandatory Integrity Level. Normally, tokens are manufactured exclusively by the Local Security Authority Subsystem Service (<xhtml:code>lsass.exe</xhtml:code>) following successful authentication.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a token object`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeCreateTokenPrivilege.ps1">Download Script: Configure-PawUraSeCreateTokenPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeCreateTokenPrivilege.ps1
# Configure-PawUraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeCreateTokenPrivilegeStatus.ps1">Download Script: Get-PawUraSeCreateTokenPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeCreateTokenPrivilegeStatus.ps1
# Get-PawUraSeCreateTokenPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatetokenprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateTokenPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeCreateTokenPrivilege.ps1
# Configure-PawUraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7098" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-099" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-099] Configure User Rights: Create global objects for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-105](../../08-endpoints/user-rights/configure-ura-secreateglobalprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-secreateglobalprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateGlobalPrivilege</xhtml:code> allows a process to create named kernel and user objects (such as named pipes, shared memory sections, mutexes, and events) in the <xhtml:code>\BaseNamedObjects</xhtml:code> global namespace accessible across all terminal services sessions and interactive logon sessions. In terminal services and multi-user Windows environments, each interactive session is isolated into a private namespace (<xhtml:code>\Sessions\X\BaseNamedObjects</xhtml:code>). The global namespace is reserved for system services that must communicate across session boundaries.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create global objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService), *S-1-5-32-544 (Administrators), *S-1-5-6 (Service)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeCreateGlobalPrivilege.ps1">Download Script: Configure-PawUraSeCreateGlobalPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeCreateGlobalPrivilege.ps1
# Configure-PawUraSeCreateGlobalPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreateglobalprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreateglobalprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateGlobalPrivilege\s*=") {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeCreateGlobalPrivilegeStatus.ps1">Download Script: Get-PawUraSeCreateGlobalPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeCreateGlobalPrivilegeStatus.ps1
# Get-PawUraSeCreateGlobalPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreateglobalprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateGlobalPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeCreateGlobalPrivilege.ps1
# Configure-PawUraSeCreateGlobalPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreateglobalprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreateglobalprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateGlobalPrivilege\s*=") {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7099" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-100" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-100] Configure User Rights: Create permanent shared objects for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-106](../../08-endpoints/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-115](../../02-domain-controllers/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-secreatepermanentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePermanentPrivilege</xhtml:code> allows a process to create permanent object directory objects in the Windows Object Manager namespace (<xhtml:code>\DirectoryObject</xhtml:code>) via APIs like <xhtml:code>NtCreateDirectoryObject</xhtml:code>. Unlike standard kernel objects which are automatically destroyed when their last handle is closed, permanent objects persist in the object manager namespace across process terminations until explicitly unlinked or until system reboot.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create permanent shared objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeCreatePermanentPrivilege.ps1">Download Script: Configure-PawUraSeCreatePermanentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeCreatePermanentPrivilege.ps1
# Configure-PawUraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeCreatePermanentPrivilegeStatus.ps1">Download Script: Get-PawUraSeCreatePermanentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeCreatePermanentPrivilegeStatus.ps1
# Get-PawUraSeCreatePermanentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepermanentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePermanentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeCreatePermanentPrivilege.ps1
# Configure-PawUraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7100" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-101" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-101] Configure User Rights: Debug programs for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-108](../../08-endpoints/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-116](../../02-domain-controllers/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sedebugprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDebugPrivilege</xhtml:code> allows a process to attach a debugger to any running process on the system, completely overriding the target process security descriptor and Discretionary Access Control List (DACL). When enabled, calls to <xhtml:code>OpenProcess</xhtml:code> with permissions such as <xhtml:code>PROCESS_ALL_ACCESS</xhtml:code> or <xhtml:code>PROCESS_VM_READ</xhtml:code> succeed even against processes owned by other users or <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>. This privilege is intended strictly for kernel/application developers debugging live processes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Debug programs`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeDebugPrivilege.ps1">Download Script: Configure-PawUraSeDebugPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeDebugPrivilege.ps1
# Configure-PawUraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeDebugPrivilegeStatus.ps1">Download Script: Get-PawUraSeDebugPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeDebugPrivilegeStatus.ps1
# Get-PawUraSeDebugPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedebugprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDebugPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeDebugPrivilege.ps1
# Configure-PawUraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7101" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-102" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-102] Configure User Rights: Enable computer and user accounts to be trusted for delegation for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-109](../../08-endpoints/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-122](../../02-domain-controllers/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seenabledelegationprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeEnableDelegationPrivilege</xhtml:code> allows a security principal to modify the <xhtml:code>userAccountControl</xhtml:code> attribute on Active Directory user and computer objects to enable Kerberos Delegation flags: (1) <xhtml:code>TRUSTED_FOR_DELEGATION</xhtml:code> (Unconstrained Delegation); (2) <xhtml:code>TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION</xhtml:code> (Constrained Delegation with Protocol Transition / S4U2Self). Kerberos delegation permits a service to impersonate an authenticated user to access back-end resources on their behalf.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Enable computer and user accounts to be trusted for delegation`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeEnableDelegationPrivilege.ps1">Download Script: Configure-PawUraSeEnableDelegationPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeEnableDelegationPrivilege.ps1
# Configure-PawUraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = ")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeEnableDelegationPrivilegeStatus.ps1">Download Script: Get-PawUraSeEnableDelegationPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeEnableDelegationPrivilegeStatus.ps1
# Get-PawUraSeEnableDelegationPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seenabledelegationprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeEnableDelegationPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeEnableDelegationPrivilege.ps1
# Configure-PawUraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = ")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7102" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-103" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-103] Configure User Rights: Force shutdown from a remote system for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-110](../../08-endpoints/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-123](../../02-domain-controllers/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seremoteshutdownprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRemoteShutdownPrivilege</xhtml:code> allows a user authenticating over the network to invoke remote system shutdown and reboot APIs (such as <xhtml:code>InitiateSystemShutdownEx</xhtml:code> or <xhtml:code>shutdown.exe /m \\computer</xhtml:code>). This function is exposed over named pipe <xhtml:code>\PIPE\InitShutdown</xhtml:code> and RPC interface <xhtml:code>winreg</xhtml:code>/<xhtml:code>shutdown</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Force shutdown from a remote system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeRemoteShutdownPrivilege.ps1">Download Script: Configure-PawUraSeRemoteShutdownPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeRemoteShutdownPrivilege.ps1
# Configure-PawUraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeRemoteShutdownPrivilegeStatus.ps1">Download Script: Get-PawUraSeRemoteShutdownPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeRemoteShutdownPrivilegeStatus.ps1
# Get-PawUraSeRemoteShutdownPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seremoteshutdownprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRemoteShutdownPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeRemoteShutdownPrivilege.ps1
# Configure-PawUraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7103" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-104" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-104] Configure User Rights: Impersonate a client after authentication for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-111](../../08-endpoints/user-rights/configure-ura-seimpersonateprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seimpersonateprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeImpersonatePrivilege</xhtml:code> grants a program the ability to impersonate a client that has connected to its local RPC interfaces, named pipes, or COM servers via <xhtml:code>ImpersonateNamedPipeClient</xhtml:code>, <xhtml:code>CoImpersonateClient</xhtml:code>, or <xhtml:code>RpcImpersonateClient</xhtml:code>. Impersonation allows a server process to temporarily run in the security context of the calling client to verify access permissions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Impersonate a client after authentication`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService), *S-1-5-32-544 (Administrators), *S-1-5-6 (Service)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeImpersonatePrivilege.ps1">Download Script: Configure-PawUraSeImpersonatePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeImpersonatePrivilege.ps1
# Configure-PawUraSeImpersonatePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seimpersonateprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seimpersonateprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeImpersonatePrivilege\s*=") {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeImpersonatePrivilegeStatus.ps1">Download Script: Get-PawUraSeImpersonatePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeImpersonatePrivilegeStatus.ps1
# Get-PawUraSeImpersonatePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seimpersonateprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeImpersonatePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeImpersonatePrivilege.ps1
# Configure-PawUraSeImpersonatePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seimpersonateprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seimpersonateprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeImpersonatePrivilege\s*=") {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7104" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-105" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-105] Configure User Rights: Load and unload device drivers for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-113](../../08-endpoints/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-125](../../02-domain-controllers/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seloaddriverprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLoadDriverPrivilege</xhtml:code> allows a process to dynamically load and unload kernel-mode device drivers (<xhtml:code>.sys</xhtml:code> files) via <xhtml:code>NtLoadDriver</xhtml:code> or the Service Control Manager (<xhtml:code>CreateService</xhtml:code> with <xhtml:code>SERVICE_KERNEL_DRIVER</xhtml:code>). Kernel-mode drivers execute in Ring 0 with unrestricted hardware access, full kernel memory read/write permissions, and the ability to execute any CPU instruction.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Load and unload device drivers`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeLoadDriverPrivilege.ps1">Download Script: Configure-PawUraSeLoadDriverPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeLoadDriverPrivilege.ps1
# Configure-PawUraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeLoadDriverPrivilegeStatus.ps1">Download Script: Get-PawUraSeLoadDriverPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeLoadDriverPrivilegeStatus.ps1
# Get-PawUraSeLoadDriverPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seloaddriverprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLoadDriverPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeLoadDriverPrivilege.ps1
# Configure-PawUraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7105" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-106" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-106] Configure User Rights: Lock pages in memory for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-114](../../08-endpoints/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-126](../../02-domain-controllers/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-selockmemoryprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLockMemoryPrivilege</xhtml:code> allows a process to lock physical memory pages in RAM using APIs such as <xhtml:code>VirtualLock</xhtml:code> and Address Windowing Extensions (AWE) via <xhtml:code>AllocateUserPhysicalPages</xhtml:code>. Locking pages prevents the Windows virtual memory manager from paging data out to disk in <xhtml:code>pagefile.sys</xhtml:code>, ensuring high-performance memory retention.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Lock pages in memory`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeLockMemoryPrivilege.ps1">Download Script: Configure-PawUraSeLockMemoryPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeLockMemoryPrivilege.ps1
# Configure-PawUraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeLockMemoryPrivilegeStatus.ps1">Download Script: Get-PawUraSeLockMemoryPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeLockMemoryPrivilegeStatus.ps1
# Get-PawUraSeLockMemoryPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_selockmemoryprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLockMemoryPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeLockMemoryPrivilege.ps1
# Configure-PawUraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7106" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-107" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-107] Configure User Rights: Manage auditing and security log for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-115](../../08-endpoints/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-129](../../02-domain-controllers/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sesecurityprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSecurityPrivilege</xhtml:code> controls access to the Windows Security Event Log (<xhtml:code>Security.evtx</xhtml:code>) and governs the ability to view, configure, and clear the security log, as well as specify object auditing options (System Access Control Lists - SACLs) on files, registry keys, and directory objects via <xhtml:code>ACCESS_SYSTEM_SECURITY</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Manage auditing and security log`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeSecurityPrivilege.ps1">Download Script: Configure-PawUraSeSecurityPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeSecurityPrivilege.ps1
# Configure-PawUraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeSecurityPrivilegeStatus.ps1">Download Script: Get-PawUraSeSecurityPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeSecurityPrivilegeStatus.ps1
# Get-PawUraSeSecurityPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesecurityprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSecurityPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeSecurityPrivilege.ps1
# Configure-PawUraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7107" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-108" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-108] Configure User Rights: Modify firmware environment values for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-116](../../08-endpoints/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-130](../../02-domain-controllers/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sesystemenvironmentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemEnvironmentPrivilege</xhtml:code> allows a process to query and modify Non-Volatile RAM (NVRAM) firmware environment variables via Win32 APIs <xhtml:code>GetFirmwareEnvironmentVariable</xhtml:code> and <xhtml:code>SetFirmwareEnvironmentVariable</xhtml:code>. NVRAM variables govern UEFI boot sequences, Secure Boot policies, boot configuration data (BCD) handoffs, and hardware configuration flags.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Modify firmware environment values`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeSystemEnvironmentPrivilege.ps1">Download Script: Configure-PawUraSeSystemEnvironmentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeSystemEnvironmentPrivilege.ps1
# Configure-PawUraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeSystemEnvironmentPrivilegeStatus.ps1">Download Script: Get-PawUraSeSystemEnvironmentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeSystemEnvironmentPrivilegeStatus.ps1
# Get-PawUraSeSystemEnvironmentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemenvironmentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemEnvironmentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeSystemEnvironmentPrivilege.ps1
# Configure-PawUraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7108" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-109" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-109] Configure User Rights: Perform volume maintenance tasks for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-117](../../08-endpoints/user-rights/configure-ura-semanagevolumeprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-semanagevolumeprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeManageVolumePrivilege</xhtml:code> allows a process to perform low-level disk and volume maintenance tasks, including running defragmentation tools, modifying volume quotas, and invoking the <xhtml:code>SetFileValidData</xhtml:code> Win32 API. The <xhtml:code>SetFileValidData</xhtml:code> function allows a caller to extend the valid data length of an allocated file without zeroing out the intervening disk clusters.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Perform volume maintenance tasks`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeManageVolumePrivilege.ps1">Download Script: Configure-PawUraSeManageVolumePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeManageVolumePrivilege.ps1
# Configure-PawUraSeManageVolumePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semanagevolumeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semanagevolumeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeManageVolumePrivilege\s*=") {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeManageVolumePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeManageVolumePrivilegeStatus.ps1">Download Script: Get-PawUraSeManageVolumePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeManageVolumePrivilegeStatus.ps1
# Get-PawUraSeManageVolumePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_semanagevolumeprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeManageVolumePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeManageVolumePrivilege.ps1
# Configure-PawUraSeManageVolumePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semanagevolumeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semanagevolumeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeManageVolumePrivilege\s*=") {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeManageVolumePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7109" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-110" severity="low" weight="10.0" selected="false">
        <title>[REQ-PAW-110] Configure User Rights: Profile single process for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-118](../../08-endpoints/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-131](../../02-domain-controllers/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-seprofilesingleprocessprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeProfileSingleProcessPrivilege</xhtml:code> allows a process to monitor and profile the performance and execution metrics of non-system processes using Windows performance sampling APIs. Profiling tools monitor instruction execution rates, thread context switches, memory cache behavior, and execution sampling.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Profile single process`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeProfileSingleProcessPrivilege.ps1">Download Script: Configure-PawUraSeProfileSingleProcessPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeProfileSingleProcessPrivilege.ps1
# Configure-PawUraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeProfileSingleProcessPrivilegeStatus.ps1">Download Script: Get-PawUraSeProfileSingleProcessPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeProfileSingleProcessPrivilegeStatus.ps1
# Get-PawUraSeProfileSingleProcessPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seprofilesingleprocessprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeProfileSingleProcessPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeProfileSingleProcessPrivilege.ps1
# Configure-PawUraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7110" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-111" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-111] Configure User Rights: Restore files and directories for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-121](../../08-endpoints/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-132](../../02-domain-controllers/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-serestoreprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRestorePrivilege</xhtml:code> grants the caller the capability to bypass all write-access security controls (DACLs) across the entire NTFS filesystem and Windows Registry. When a process opens a file or registry key handle specifying <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> in Win32 APIs, the kernel explicitly bypasses standard security descriptor DACL checks, allowing the process to write to, overwrite, or delete any file or key on the system. In addition, this privilege grants the ability to set any valid user or group SID as the owner of an object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Restore files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeRestorePrivilege.ps1">Download Script: Configure-PawUraSeRestorePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeRestorePrivilege.ps1
# Configure-PawUraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeRestorePrivilegeStatus.ps1">Download Script: Get-PawUraSeRestorePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeRestorePrivilegeStatus.ps1
# Get-PawUraSeRestorePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_serestoreprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRestorePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeRestorePrivilege.ps1
# Configure-PawUraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7111" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-112" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-112] Configure User Rights: Take ownership of files or other objects for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-122](../../08-endpoints/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-135](../../02-domain-controllers/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-setakeownershipprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTakeOwnershipPrivilege</xhtml:code> allows a user to take ownership of any securable object in the operating system (files, directories, registry keys, Active Directory objects, printers, services) by writing the caller's SID into the object security descriptor owner field via <xhtml:code>SetNamedSecurityInfo</xhtml:code> or <xhtml:code>SetSecurityInfo</xhtml:code>. The Windows security model grants the owner of an object implicit <xhtml:code>WRITE_DAC</xhtml:code> authority.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Take ownership of files or other objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeTakeOwnershipPrivilege.ps1">Download Script: Configure-PawUraSeTakeOwnershipPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeTakeOwnershipPrivilege.ps1
# Configure-PawUraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeTakeOwnershipPrivilegeStatus.ps1">Download Script: Get-PawUraSeTakeOwnershipPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeTakeOwnershipPrivilegeStatus.ps1
# Get-PawUraSeTakeOwnershipPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setakeownershipprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTakeOwnershipPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeTakeOwnershipPrivilege.ps1
# Configure-PawUraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7112" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-113" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-113] Configure User Rights: Deny access to this computer from the network for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-124](../../08-endpoints/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-117](../../02-domain-controllers/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sedenynetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyNetworkLogonRight</xhtml:code> explicitly prevents specified security principals from authenticating over network protocols (SMB, RPC, WMI, WinRM, LDAP, etc. - Logon Type 3). Network logons represent the primary highway for lateral movement and remote compromise in Active Directory environments. Enforcing an explicit deny stops network authentication regardless of share-level or NTFS-level permissions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny access to this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-113 (Local Account), *S-1-5-114 (Local Account and member of Administrators group)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeDenyNetworkLogonRight.ps1">Download Script: Configure-PawUraSeDenyNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeDenyNetworkLogonRight.ps1
# Configure-PawUraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeDenyNetworkLogonRightStatus.ps1">Download Script: Get-PawUraSeDenyNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeDenyNetworkLogonRightStatus.ps1
# Get-PawUraSeDenyNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenynetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-113,*S-1-5-114"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeDenyNetworkLogonRight.ps1
# Configure-PawUraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7113" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-114" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-114] Configure User Rights: Deny log on through Remote Desktop Services for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) dedicated to Tier 0 and critical administrative functions. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to standard baseline [REQ-END-125](../../08-endpoints/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-121](../../02-domain-controllers/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809 and above) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-rights/configure-ura-sedenyremoteinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyRemoteInteractiveLogonRight</xhtml:code> explicitly denies designated accounts the ability to establish Remote Desktop Protocol (RDP) sessions (Logon Type 10) on the target system. RDP exposes a full graphical interactive session over TCP port 3389, providing an attacker with interactive desktop capabilities and loading user credentials into memory.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 0 PAW systems (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on through Remote Desktop Services`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-113 (Local Account), *S-1-5-114 (Local Account and member of Administrators group)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1">Download Script: Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1
# Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawUraSeDenyRemoteInteractiveLogonRightStatus.ps1">Download Script: Get-PawUraSeDenyRemoteInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUraSeDenyRemoteInteractiveLogonRightStatus.ps1
# Get-PawUraSeDenyRemoteInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenyremoteinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyRemoteInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-113,*S-1-5-114"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1
# Configure-PawUraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7114" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_User_Profile_Restrictions">
      <title>User Profile Restrictions</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-115" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-115] User Profile: Toast Notifications Lock Screen Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-126](../../08-endpoints/user-profile/configure-up-toast-notifications.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-toast-notifications.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) operate in high-security operations centers (SOC/NOC) or dedicated administrative enclaves. Tier 0 administrative operators interact with domain controllers, public key infrastructure (PKI), and cloud identity tenants. Allowing application notifications to render above the lock screen exposes highly confidential administrative context and authentication challenges to physical observation.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Start Menu and Taskbar \ Notifications</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Turn off toast notifications on the lock screen</xhtml:strong> and set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
            <xhtml:li>
              <xhtml:em>(Optional Defense-in-Depth)</xhtml:em> Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ System \ Logon</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Set </xhtml:em>
              <xhtml:em>Turn off app notifications on the lock screen</xhtml:em>
              <xhtml:em> to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable toast notifications on the lock screen on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUptoastnotifications.ps1">Download Script: Configure-PawUptoastnotifications.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUptoastnotifications.ps1
Write-Host "Applying User Profile restriction: toast-notifications..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoToastApplicationNotificationOnLockScreen" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUptoastnotificationsStatus.ps1">Download Script: Get-PawUptoastnotificationsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUptoastnotificationsStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUptoastnotifications.ps1
Write-Host "Applying User Profile restriction: toast-notifications..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoToastApplicationNotificationOnLockScreen" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7115" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-116" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-116] User Profile: Spotlight and Consumer Features Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-127](../../08-endpoints/user-profile/configure-up-spotlight-consumer.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-spotlight-consumer.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) operate in dedicated management enclaves with restricted internet egress. Connecting to public consumer clouds to download wallpapers, marketing suggestions, or consumer games introduces unvetted network connections, violates administrative isolation, and increases attack surface on Tier 0 assets.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Cloud Content</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Microsoft consumer experiences</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Cloud Content</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Do not show third-party suggestions in Windows spotlight</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Configure Windows spotlight on lock screen</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows spotlight on desktop</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Spotlight and Consumer Features restrictions on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpspotlightconsumer.ps1">Download Script: Configure-PawUpspotlightconsumer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpspotlightconsumer.ps1
Write-Host "Applying User Profile restriction: spotlight-consumer..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableThirdPartySuggestions" -Value "1" -Type DWord -Force
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "ConfigureWindowsSpotlight" -Value "2" -Type DWord -Force
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableSpotlightCollectionOnDesktop" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpspotlightconsumerStatus.ps1">Download Script: Get-PawUpspotlightconsumerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpspotlightconsumerStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1"
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2"
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpspotlightconsumer.ps1
Write-Host "Applying User Profile restriction: spotlight-consumer..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableThirdPartySuggestions" -Value "1" -Type DWord -Force
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "ConfigureWindowsSpotlight" -Value "2" -Type DWord -Force
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableSpotlightCollectionOnDesktop" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7116" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-117" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-117] User Profile: Windows Copilot Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-128](../../08-endpoints/user-profile/configure-up-windows-copilot.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 11 Enterprise, Windows 10 Enterprise (version 1809 and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-windows-copilot.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) handle the most sensitive infrastructure secrets in the Active Directory enterprise: Domain Controller recovery keys, Kerberos KRBTGT hashes, schema definitions, and cloud tenant administrative tokens. Generative AI assistants integrated into the operating system shell present an existential security and confidentiality hazard on dedicated Tier 0 management consoles.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Windows Copilot</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows Copilot</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Copilot</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows Copilot</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Windows Copilot on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpwindowscopilot.ps1">Download Script: Configure-PawUpwindowscopilot.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpwindowscopilot.ps1
Write-Host "Applying User Profile restriction: windows-copilot..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "TurnOffWindowsCopilot" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpwindowscopilotStatus.ps1">Download Script: Get-PawUpwindowscopilotStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpwindowscopilotStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpwindowscopilot.ps1
Write-Host "Applying User Profile restriction: windows-copilot..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "TurnOffWindowsCopilot" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7117" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-118" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-118] User Profile: In-Place Sharing Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-129](../../08-endpoints/user-profile/configure-up-inplace-sharing.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-inplace-sharing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to directory administration, identity synchronization, and domain-level maintenance. Administrative sessions on PAWs interact with sensitive directory export files (<xhtml:code>ntds.dit</xhtml:code> snippets, LDIFDE exports, sensitive PowerShell scripts, and recovery key backups). Allowing interactive, peer-to-peer, or modern shell file sharing from a PAW shatters data containment and provides immediate exfiltration channels.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off in-place sharing</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off in-place sharing</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure In-Place Sharing restrictions on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpinplacesharing.ps1">Download Script: Configure-PawUpinplacesharing.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpinplacesharing.ps1
Write-Host "Applying User Profile restriction: inplace-sharing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoInplaceSharing" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpinplacesharingStatus.ps1">Download Script: Get-PawUpinplacesharingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpinplacesharingStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpinplacesharing.ps1
Write-Host "Applying User Profile restriction: inplace-sharing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoInplaceSharing" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7118" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-119" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-119] User Profile: Shell RunAs User Suppression for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-130](../../08-endpoints/user-profile/configure-up-runas-suppression.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-runas-suppression.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) operate under strict dedicated role segregation. An administrator logging into a Tier 0 PAW authenticates directly with their Tier 0 privileged identity (e.g., Domain Admin smart card or FIDO2 key). The Windows Explorer "Run as different user" context menu verb (<xhtml:code>runasuser</xhtml:code>) invites multi-account usage patterns, credential confusion, and potential interactive credential theft.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create four Registry Items with the following parameters:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SuppressionPolicy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>4096</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Paths</xhtml:em>*:</xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\batfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\cmdfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\exefile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\mscfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Shell RunAs User suppression on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUprunassuppression.ps1">Download Script: Configure-PawUprunassuppression.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUprunassuppression.ps1
Write-Host "Applying User Profile restriction: runas-suppression..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUprunassuppressionStatus.ps1">Download Script: Get-PawUprunassuppressionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUprunassuppressionStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUprunassuppression.ps1
Write-Host "Applying User Profile restriction: runas-suppression..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7119" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-120" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-120] User Profile: Personalization and Privacy Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-131](../../08-endpoints/user-profile/configure-up-personalization-privacy.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-personalization-privacy.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) serve as the trusted execution environment for managing Active Directory Domain Services, forest trusts, and cryptographic root keys. Permitting multimedia sensors, unauthenticated camera feeds, dynamic slideshow image parsing, voice assistants, or keystroke learning databases on a Tier 0 console creates intolerable physical security, acoustic surveillance, and local memory exploitation risks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Control Panel \ Personalization</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Prevent enabling lock screen camera</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Prevent enabling lock screen slide show</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ App Privacy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Let Windows apps activate with voice above lock</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>In the drop-down menu, select: <xhtml:strong>Force Deny</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Control Panel \ Regional and Language Options \ Handwriting personalization</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off automatic learning</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Personalization and Privacy restrictions on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUppersonalizationprivacy.ps1">Download Script: Configure-PawUppersonalizationprivacy.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUppersonalizationprivacy.ps1
Write-Host "Applying User Profile restriction: personalization-privacy..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUppersonalizationprivacyStatus.ps1">Download Script: Get-PawUppersonalizationprivacyStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUppersonalizationprivacyStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUppersonalizationprivacy.ps1
Write-Host "Applying User Profile restriction: personalization-privacy..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7120" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-121" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-121] User Profile: Group Policy Registry Policy Processing Behaviors for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to reciprocal baseline [REQ-END-132](../../08-endpoints/user-profile/configure-up-gp-processing.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-gp-processing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) enforce the most stringent security configurations across the enterprise to safeguard Tier 0 identity assets. Group Policy client configuration is applied by specialized Client-Side Extensions (CSEs). The GUID <xhtml:code>{35378EAC-683F-11D2-A89A-00C04FBBCFA2}</xhtml:code> corresponds to the core <xhtml:strong>Registry Client-Side Extension</xhtml:strong> (<xhtml:code>gptext.dll</xhtml:code>), which reads and applies the administrative templates and security settings packaged within Group Policy Objects.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ System \ Group Policy</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Configure Registry policy processing</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Ensure </xhtml:em>
              <xhtml:em>Do not apply during periodic background processing</xhtml:em>
              <xhtml:em> is </xhtml:em>
              <xhtml:em>unchecked</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce policy application using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the Registry CSE processing behaviors on PAWs:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpgpprocessing.ps1">Download Script: Configure-PawUpgpprocessing.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpgpprocessing.ps1
Write-Host "Applying User Profile restriction: gp-processing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpgpprocessingStatus.ps1">Download Script: Get-PawUpgpprocessingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpgpprocessingStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpgpprocessing.ps1
Write-Host "Applying User Profile restriction: gp-processing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7121" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-122" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-122] User Profile: Telemetry and Inventory Collection Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to reciprocal baseline [REQ-END-133](../../08-endpoints/user-profile/configure-up-telemetry-inventory.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-telemetry-inventory.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) serve as the most secure bastion tier in an enterprise Active Directory deployment, operating within isolated administrative networks with strictly regulated inbound and outbound communications. Telemetry, diagnostic data collection, and application inventory background tasks represent unnecessary attack surface and data leakage risks when running on Tier 0 consoles.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Application Compatibility</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Turn off Inventory Collector</xhtml:em>
              <xhtml:em> -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Data Collection and Preview Builds</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Allow Diagnostic Data</xhtml:em>
              <xhtml:em> (or </xhtml:em>
              <xhtml:em>Allow Telemetry</xhtml:em>
              <xhtml:em>) -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em>, and choose </xhtml:em>
              <xhtml:em>Send required diagnostic data</xhtml:em>
              <xhtml:em> (or </xhtml:em>
              <xhtml:em>Diagnostic data off</xhtml:em>* / <xhtml:code>0</xhtml:code> if available).</xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Limit Enhanced diagnostic data to the minimum required by Windows Analytics</xhtml:em>
              <xhtml:em> -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce policy application with <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce inventory and telemetry restrictions on PAWs:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUptelemetryinventory.ps1">Download Script: Configure-PawUptelemetryinventory.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUptelemetryinventory.ps1
Write-Host "Applying User Profile restriction: telemetry-inventory..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUptelemetryinventoryStatus.ps1">Download Script: Get-PawUptelemetryinventoryStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUptelemetryinventoryStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUptelemetryinventory.ps1
Write-Host "Applying User Profile restriction: telemetry-inventory..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7122" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-123" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-123] User Profile: Explorer Security and Memory Protections for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-134](../../08-endpoints/user-profile/configure-up-explorer-security.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-explorer-security.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>On Privileged Access Workstations (PAWs), File Explorer (<xhtml:code>explorer.exe</xhtml:code>) provides the interactive desktop shell within which all Tier 0 administrative tasks, credential entry, and management utilities operate. If an adversary or malicious script can exploit a memory corruption vulnerability within the Explorer process, they can execute arbitrary shellcode within the interactive administrative desktop station, compromising Kerberos tickets, session tokens, and Active Directory management sessions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Turn off Data Execution Prevention for Explorer</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Turn off heap termination on corruption</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Shell Protocol Protected Mode</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Explorer security and memory protections on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpexplorersecurity.ps1">Download Script: Configure-PawUpexplorersecurity.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpexplorersecurity.ps1
Write-Host "Applying User Profile restriction: explorer-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpexplorersecurityStatus.ps1">Download Script: Get-PawUpexplorersecurityStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpexplorersecurityStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpexplorersecurity.ps1
Write-Host "Applying User Profile restriction: explorer-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7123" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-124" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-124] User Profile: Internet Explorer Options and Feeds Restrictions for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to reciprocal baseline [REQ-END-135](../../08-endpoints/user-profile/configure-up-ie-security.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-ie-security.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to high-privilege administrative tasks, such as managing Active Directory Domain Services, Azure AD Connect, PKI infrastructure, and Domain Controllers. Standard user activities—including general web browsing, personal email, and social media—are strictly forbidden on PAWs by foundational Tier 0 isolation principles.</xhtml:p>
          <xhtml:p>Even when direct interactive browsing is prohibited, background operating system components associated with legacy Internet Explorer, WinINet, and the Windows RSS Platform (<xhtml:code>msfeeds.dll</xhtml:code>, <xhtml:code>msfeedssync.exe</xhtml:code>) remain installed on Windows clients. Hardening these legacy components is essential to prevent background exploitation vectors on Tier 0 consoles.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Internet Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Disable Internet Explorer 11 as a standalone browser</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em>, and select </xhtml:em>
              <xhtml:em>Always</xhtml:em>*.</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ RSS Feeds</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Prevent downloading of enclosures</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Turn on Basic feed authentication over HTTP</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce policy application with <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Internet Explorer and RSS feed security restrictions on PAWs:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpiesecurity.ps1">Download Script: Configure-PawUpiesecurity.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpiesecurity.ps1
Write-Host "Applying User Profile restriction: ie-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpiesecurityStatus.ps1">Download Script: Get-PawUpiesecurityStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpiesecurityStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpiesecurity.ps1
Write-Host "Applying User Profile restriction: ie-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7124" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-125" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-125] User Profile: Interactive Logon Warning Banners for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-136](../../08-endpoints/user-profile/configure-up-logon-banners.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-logon-banners.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) operate at the highest classification boundary in the enterprise, dedicated strictly to Tier 0 Active Directory and cloud identity administration. Permitting automated background credential rehydration after reboots, or omitting authoritative legal notice warnings, severely undermines physical device security and legal prosecution capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Interactive logon: Message text for users attempting to log on</xhtml:strong>: Enter organizational warning text (e.g., <xhtml:code>You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring.</xhtml:code>)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Interactive logon: Message title for users attempting to log on</xhtml:strong>: Enter warning title (e.g., <xhtml:code>US Department of Defense Warning Statement</xhtml:code>)</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Logon Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Sign-in and lock last interactive user automatically after a restart or cold boot</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Interactive Logon warning banners and disable ARSO on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUplogonbanners.ps1">Download Script: Configure-PawUplogonbanners.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUplogonbanners.ps1
Write-Host "Applying User Profile restriction: logon-banners..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring." "String"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement" "String"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUplogonbannersStatus.ps1">Download Script: Get-PawUplogonbannersStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUplogonbannersStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring."
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUplogonbanners.ps1
Write-Host "Applying User Profile restriction: logon-banners..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring." "String"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement" "String"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7125" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-126" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-126] User Profile: Interactive Logon Inactivity Timeout for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to [REQ-END-137](../../08-endpoints/user-profile/configure-up-inactivity-timeout.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-inactivity-timeout.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated physical or virtual workstations exclusively utilized by Tier 0 identity administrators to manage Active Directory Domain Services, PKI root certification authorities, and privileged directory infrastructure. During an active administrative session, a PAW routinely hosts high-privilege credentials: <xhtml:em> In-memory Kerberos Ticket Granting Tickets (TGTs) belonging to Domain Admins, Enterprise Admins, or Schema Admins. </xhtml:em> Physical hardware security tokens (FIDO2 keys, PIV/CAC smart cards, YubiKeys) plugged into USB ports with unlocked PIN caching. * Open elevated PowerShell consoles, Active Directory Administrative Center sessions, and Microsoft Management Consoles (MMCs) possessing unconstrained administrative control over the directory.</xhtml:p>
          <xhtml:p>If an administrator steps away from their PAW without manually locking the console (e.g., to attend a meeting, take a phone call, or converse with colleagues), an unlocked workstation presents an existential threat to the entire Active Directory forest.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to the PAW Organizational Unit (e.g., <xhtml:code>GPO_Hardening_PAWs</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Interactive logon: Machine inactivity limit</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Define this policy setting</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Set </xhtml:em>
              <xhtml:em>The machine will be locked after</xhtml:em>*: <xhtml:code>900</xhtml:code> seconds (or <xhtml:code>600</xhtml:code> seconds for tightened Tier 0 environments)</xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce policy application using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce the machine inactivity timeout limit on PAWs:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpinactivitytimeout.ps1">Download Script: Configure-PawUpinactivitytimeout.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpinactivitytimeout.ps1
Write-Host "Applying User Profile restriction: inactivity-timeout..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpinactivitytimeoutStatus.ps1">Download Script: Get-PawUpinactivitytimeoutStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpinactivitytimeoutStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpinactivitytimeout.ps1
Write-Host "Applying User Profile restriction: inactivity-timeout..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7126" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-127" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-127] User Profile: Windows Installer Hardening for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-138](../../08-endpoints/user-profile/configure-up-installer-hardening.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-installer-hardening.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated management boundary for Tier 0 Active Directory assets. In a hardened PAW environment, local software installations are strictly restricted to enterprise-vetted administrative tooling deployed via central configuration management. Permitting any permissive Windows Installer settings—especially <xhtml:code>AlwaysInstallElevated</xhtml:code>—presents an immediate local privilege escalation hazard that could allow a non-administrative account or background worker to seize full <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code> control of the PAW.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Installer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Always install with elevated privileges</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Allow user control over installs</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Windows Installer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Always install with elevated privileges</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Add Registry Item: <xhtml:code>HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer\DisableCoInstallers</xhtml:code> = <xhtml:code>1</xhtml:code> (DWord)</xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Windows Installer hardening on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpinstallerhardening.ps1">Download Script: Configure-PawUpinstallerhardening.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpinstallerhardening.ps1
Write-Host "Applying User Profile restriction: installer-hardening..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpinstallerhardeningStatus.ps1">Download Script: Get-PawUpinstallerhardeningStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpinstallerhardeningStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpinstallerhardening.ps1
Write-Host "Applying User Profile restriction: installer-hardening..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7127" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-128" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-128] User Profile: Secondary Logon Service Lockdown for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-139](../../08-endpoints/user-profile/configure-up-seclogon-service.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-up-seclogon-service.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are architected according to the "Clean Source" principle: a PAW is dedicated strictly to a single administrative tier, and administrators log in directly with their Tier 0 credentials. The Secondary Logon service (<xhtml:code>seclogon.dll</xhtml:code>), which facilitates <xhtml:code>RunAs</xhtml:code> and <xhtml:code>CreateProcessWithLogonW</xhtml:code>, is not only unnecessary on a dedicated PAW console, but poses an acute attack surface and violates Tier 0 credential hygiene.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Secondary Logon</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Define this policy setting</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable the Secondary Logon service on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawUpseclogonservice.ps1">Download Script: Configure-PawUpseclogonservice.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawUpseclogonservice.ps1
Write-Host "Applying User Profile restriction: seclogon-service..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawUpseclogonserviceStatus.ps1">Download Script: Get-PawUpseclogonserviceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawUpseclogonserviceStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawUpseclogonservice.ps1
Write-Host "Applying User Profile restriction: seclogon-service..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7128" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-140" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-140] User Profile: Structured Exception Handling Overwrite Protection (SEHOP) for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-151](../../08-endpoints/user-profile/configure-end-up-sehop.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-sehop.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Dedicated Privileged Access Workstations (PAWs) are the cornerstone of Tier 0 infrastructure security. While PAWs predominantly run native 64-bit administrative consoles, administrative utilities, MMC snap-ins, or legacy automation tools may invoke 32-bit processes under WOW64. Enforcing Structured Exception Handling Overwrite Protection (SEHOP) system-wide prevents stack corruption exploits from subverting the exception handling mechanism on high-privilege management stations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\kernel</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>DisableExceptionChainValidation</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>DisableExceptionChainValidation</xhtml:code> requires a system restart to take effect on the kernel exception dispatcher.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce SEHOP exception chain validation on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditSehop.ps1">Download Script: Configure-PawAuditSehop.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditSehop.ps1
Write-Host "Enforcing System Mitigation control: sehop..." -ForegroundColor Cyan

# Set Registry value: DisableExceptionChainValidation
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "    Enforced DisableExceptionChainValidation = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditSehopStatus.ps1">Download Script: Get-PawAuditSehopStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditSehopStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: DisableExceptionChainValidation
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.DisableExceptionChainValidation -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditSehop.ps1
Write-Host "Enforcing System Mitigation control: sehop..." -ForegroundColor Cyan

# Set Registry value: DisableExceptionChainValidation
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "    Enforced DisableExceptionChainValidation = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7140" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-141" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-141] User Profile: Directory Protection Mode for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-152](../../08-endpoints/user-profile/configure-end-up-protection-mode.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-protection-mode.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) host the most sensitive administrative sessions in the enterprise, including Domain Admin, Enterprise Admin, and Tier 0 identity management credentials. Any unauthorized file placement, symbolic link manipulation, or DLL planting in <xhtml:code>%SystemRoot%</xhtml:code> or system object manager namespaces could allow an unprivileged attacker or rogue maintenance utility to compromise the entire workstation integrity, leading to identity store takeover.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>ProtectionMode</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>ProtectionMode</xhtml:code> requires a computer restart to apply to the Session Manager during initial boot.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Directory Protection Mode on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditProtectionmode.ps1">Download Script: Configure-PawAuditProtectionmode.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditProtectionmode.ps1
Write-Host "Enforcing System Mitigation control: protection-mode..." -ForegroundColor Cyan

# Set Registry value: ProtectionMode
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -Value 1 -Type DWord -Force
Write-Host "    Enforced ProtectionMode = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditProtectionmodeStatus.ps1">Download Script: Get-PawAuditProtectionmodeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditProtectionmodeStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: ProtectionMode
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.ProtectionMode -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditProtectionmode.ps1
Write-Host "Enforcing System Mitigation control: protection-mode..." -ForegroundColor Cyan

# Set Registry value: ProtectionMode
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -Value 1 -Type DWord -Force
Write-Host "    Enforced ProtectionMode = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7141" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-142" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-142] User Profile: Address Space Layout Randomization (ASLR) Image Relocation for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-153](../../08-endpoints/user-profile/configure-end-up-aslr-relocation.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-aslr-relocation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) host high-integrity administrative tooling, PowerShell sessions, and directory management utilities where memory safety is critical to preventing credential harvesting. Mandatory Address Space Layout Randomization (ASLR) image relocation enforces systematic randomization across all executable binaries and loaded DLLs, depriving adversaries of static memory targets for Return-Oriented Programming (ROP) exploitation.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>MoveImages</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>4294967295</xhtml:code> (Decimal) or <xhtml:code>0xFFFFFFFF</xhtml:code> (Hexadecimal)</xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>MoveImages</xhtml:code> requires a computer restart to apply to core operating system kernel processes.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce system-wide ASLR image relocation on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAslrrelocation.ps1">Download Script: Configure-PawAuditAslrrelocation.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAslrrelocation.ps1
Write-Host "Enforcing System Mitigation control: aslr-relocation..." -ForegroundColor Cyan

# Set Registry value: MoveImages
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -Value 4294967295 -Type DWord -Force
Write-Host "    Enforced MoveImages = 4294967295" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditAslrrelocationStatus.ps1">Download Script: Get-PawAuditAslrrelocationStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAslrrelocationStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: MoveImages
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.MoveImages -ne 4294967295) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAslrrelocation.ps1
Write-Host "Enforcing System Mitigation control: aslr-relocation..." -ForegroundColor Cyan

# Set Registry value: MoveImages
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -Value 4294967295 -Type DWord -Force
Write-Host "    Enforced MoveImages = 4294967295" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7142" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-143" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-143] User Profile: Speculative Execution Mitigations (Spectre/Meltdown) for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-154](../../08-endpoints/user-profile/configure-end-up-speculative-mitigations.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-speculative-mitigations.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to managing Tier 0 directory assets, where sensitive Kerberos TGTs, domain administrator password hashes, and enterprise PKI keys are processed in volatile memory. Speculative execution side-channel vulnerabilities (Spectre, Meltdown, MDS) allow unprivileged local code or sandboxed scripts to circumvent hardware security boundaries, leaking confidential kernel memory across address spaces.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>FeatureSettingsOverride</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>72</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a second Registry Item:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>FeatureSettingsOverrideMask</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>3</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: A computer restart is required for the Windows kernel to initialize speculative CPU execution mitigations.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce speculative execution mitigations on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditSpeculativemitigations.ps1">Download Script: Configure-PawAuditSpeculativemitigations.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditSpeculativemitigations.ps1
Write-Host "Enforcing System Mitigation control: speculative-mitigations..." -ForegroundColor Cyan

# Set Registry value: FeatureSettingsOverride
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -Value 72 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverride = 72" -ForegroundColor Green

# Set Registry value: FeatureSettingsOverrideMask
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -Value 3 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverrideMask = 3" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditSpeculativemitigationsStatus.ps1">Download Script: Get-PawAuditSpeculativemitigationsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditSpeculativemitigationsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: FeatureSettingsOverride
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.FeatureSettingsOverride -ne 72) {
    $script:Vulnerable = $true
}

# Audit Registry value: FeatureSettingsOverrideMask
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.FeatureSettingsOverrideMask -ne 3) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditSpeculativemitigations.ps1
Write-Host "Enforcing System Mitigation control: speculative-mitigations..." -ForegroundColor Cyan

# Set Registry value: FeatureSettingsOverride
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -Value 72 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverride = 72" -ForegroundColor Green

# Set Registry value: FeatureSettingsOverrideMask
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -Value 3 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverrideMask = 3" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7143" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-144" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-144] User Profile: Authenticode Signature Certificate Padding Check for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-155](../../08-endpoints/user-profile/configure-end-up-cert-padding.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-cert-padding.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>On Privileged Access Workstations (PAWs), Windows Defender Application Control (WDAC) and AppLocker enforce rigorous publisher signature rules to guarantee that only cryptographically verified, Microsoft-signed, or enterprise-approved binaries can execute. A vulnerability in legacy Authenticode processing (CVE-2013-3900) allows adversaries to append unauthorized code or secondary payloads to signed PE files without breaking the signature, creating a critical evasion pathway on administrative systems.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> (Native 64-bit) and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>Software\Microsoft\Cryptography\Wintrust\Config</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>EnableCertPaddingCheck</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> (WOW64 32-bit) and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>EnableCertPaddingCheck</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Authenticode certificate padding validation on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditCertpadding.ps1">Download Script: Configure-PawAuditCertpadding.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditCertpadding.ps1
Write-Host "Enforcing System Mitigation control: cert-padding..." -ForegroundColor Cyan

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditCertpaddingStatus.ps1">Download Script: Get-PawAuditCertpaddingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditCertpaddingStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: EnableCertPaddingCheck
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.EnableCertPaddingCheck -ne 1) {
    $script:Vulnerable = $true
}

# Audit Registry value: EnableCertPaddingCheck
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.EnableCertPaddingCheck -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditCertpadding.ps1
Write-Host "Enforcing System Mitigation control: cert-padding..." -ForegroundColor Cyan

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7144" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-145" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-145] User Profile: Command Processor Batch File Locking for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-156](../../08-endpoints/user-profile/configure-end-up-lock-batch-files.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-lock-batch-files.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to directory administration, identity synchronization, and domain-level maintenance. Administrative batch scripts running on PAWs often operate in high-integrity or <xhtml:code>SYSTEM</xhtml:code> contexts to orchestrate directory backups, certificate rollover tasks, or network diagnostics. Allowing concurrent processes to modify active scripts creates a critical privilege escalation vector.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Command Processor</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LockBatchFilesWhenInUse</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Command Processor batch file locking on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditLockbatchfiles.ps1">Download Script: Configure-PawAuditLockbatchfiles.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditLockbatchfiles.ps1
Write-Host "Enforcing System Mitigation control: lock-batch-files..." -ForegroundColor Cyan

# Set Registry value: LockBatchFilesWhenInUse
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Command Processor")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -Value 1 -Type DWord -Force
Write-Host "    Enforced LockBatchFilesWhenInUse = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditLockbatchfilesStatus.ps1">Download Script: Get-PawAuditLockbatchfilesStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditLockbatchfilesStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: LockBatchFilesWhenInUse
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LockBatchFilesWhenInUse -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditLockbatchfiles.ps1
Write-Host "Enforcing System Mitigation control: lock-batch-files..." -ForegroundColor Cyan

# Set Registry value: LockBatchFilesWhenInUse
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Command Processor")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -Value 1 -Type DWord -Force
Write-Host "    Enforced LockBatchFilesWhenInUse = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7145" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-146" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-146] User Profile: Time-Travel Debugging (TTD) Recording Policy for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-157](../../08-endpoints/user-profile/configure-end-up-ttd-recording.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-ttd-recording.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) process the highest-value authentication secrets in the enterprise, including Kerberos Ticket Granting Tickets (TGTs), domain administrator password hashes, and directory replication metadata. Time-Travel Debugging (TTD) records complete CPU instruction sequences and process memory states into persistent <xhtml:code>.run</xhtml:code> trace files. If left unconstrained on a PAW, an adversary could weaponize TTD to harvest Tier 0 credentials without triggering traditional LSASS access alerts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\TTD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>RecordingPolicy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Time-Travel Debugging recording on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditTtdrecording.ps1">Download Script: Configure-PawAuditTtdrecording.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditTtdrecording.ps1
Write-Host "Enforcing System Mitigation control: ttd-recording..." -ForegroundColor Cyan

# Set Registry value: RecordingPolicy
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\TTD")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -Value 2 -Type DWord -Force
Write-Host "    Enforced RecordingPolicy = 2" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditTtdrecordingStatus.ps1">Download Script: Get-PawAuditTtdrecordingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditTtdrecordingStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: RecordingPolicy
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.RecordingPolicy -ne 2) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditTtdrecording.ps1
Write-Host "Enforcing System Mitigation control: ttd-recording..." -ForegroundColor Cyan

# Set Registry value: RecordingPolicy
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\TTD")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -Value 2 -Type DWord -Force
Write-Host "    Enforced RecordingPolicy = 2" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7146" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-147" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-147] User Profile: Trusted Root Store Protected Roots Certificate Restriction for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-158](../../08-endpoints/user-profile/configure-end-up-protected-roots.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-protected-roots.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>On Privileged Access Workstations (PAWs), cryptographic trust validation is paramount. Administrative sessions connect to Domain Controllers via LDAPS, manage Active Directory Certificate Services (AD CS), authenticate via smart cards / Windows Hello for Business, and execute digitally signed PowerShell scripts. Allowing any local or interactive addition of root certificates to the PAW root store creates a catastrophic risk of rogue CA insertion, enabling transparent interception of Tier 0 authentication traffic.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Flags</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Protected Roots certificate restrictions on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditProtectedroots.ps1">Download Script: Configure-PawAuditProtectedroots.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditProtectedroots.ps1
Write-Host "Enforcing System Mitigation control: protected-roots..." -ForegroundColor Cyan

# Set Registry value: Flags
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -Value 1 -Type DWord -Force
Write-Host "    Enforced Flags = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditProtectedrootsStatus.ps1">Download Script: Get-PawAuditProtectedrootsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditProtectedrootsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: Flags
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.Flags -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditProtectedroots.ps1
Write-Host "Enforcing System Mitigation control: protected-roots..." -ForegroundColor Cyan

# Set Registry value: Flags
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -Value 1 -Type DWord -Force
Write-Host "    Enforced Flags = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7147" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-148" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-148] User Profile: Disabling Injection of AppInit DLLs for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-159](../../08-endpoints/user-profile/configure-end-up-appinit-dlls.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-appinit-dlls.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to administrative tasks against Tier 0 Active Directory Domain Controllers, Certificate Authorities, and identity infrastructure. In a PAW environment, the presence of legacy process injection pathways creates an unacceptable threat surface that could allow an attacker or malicious user-mode software to hook administrative tools (e.g., PowerShell, RSAT, MMC, <xhtml:code>dsa.msc</xhtml:code>, <xhtml:code>ntdsutil</xhtml:code>) and compromise Tier 0 credentials.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LoadAppInit_DLLs</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a secondary Registry Item to clear the DLL list:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AppInit_DLLs</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_SZ</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>""</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the AppInit DLL lockdown on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAppinitdlls.ps1">Download Script: Configure-PawAuditAppinitdlls.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAppinitdlls.ps1
Write-Host "Enforcing System Mitigation control: appinit-dlls..." -ForegroundColor Cyan

# Set Registry value: LoadAppInit_DLLs
if (-not (Test-Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows")) { New-Item -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord -Force
Write-Host "    Enforced LoadAppInit_DLLs = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditAppinitdllsStatus.ps1">Download Script: Get-PawAuditAppinitdllsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAppinitdllsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: LoadAppInit_DLLs
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LoadAppInit_DLLs -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAppinitdlls.ps1
Write-Host "Enforcing System Mitigation control: appinit-dlls..." -ForegroundColor Cyan

# Set Registry value: LoadAppInit_DLLs
if (-not (Test-Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows")) { New-Item -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord -Force
Write-Host "    Enforced LoadAppInit_DLLs = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7148" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-149" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-149] User Profile: Preservation of Attachment Zone Information for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-160](../../08-endpoints/user-profile/configure-end-up-attachment-zone.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-attachment-zone.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are strictly isolated systems dedicated to managing Tier 0 assets. Web browsing and direct email access are prohibited on PAWs. However, administrative files, deployment scripts, security patches, and utility binaries may occasionally be transferred to PAWs via approved, encrypted management channels or staging shares. Preserving Mark-of-the-Web (MOTW) zone information ensures that the operating system's internal defense layers remain fully informed of the file's external provenance.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Attachment Manager</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em>(Optionally also navigate to `Computer Configuration \ Administrative Templates \ Windows Components \ Attachment Manager`)</xhtml:em>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Policy</xhtml:em>
              <xhtml:em>: `Do not preserve zone information in file attachments` -&gt; Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em>(Note: Setting this policy to Disabled enforces SaveZoneInformation = 2, ensuring zone information is preserved).</xhtml:em>
            </xhtml:li>
            <xhtml:li>Alternatively, configure the registry value via Group Policy Preferences:</xhtml:li>
            <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Right-click </xhtml:em>
              <xhtml:em>Registry</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>New</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>Registry Item</xhtml:em>* and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SaveZoneInformation</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce the preservation of attachment zone information on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAttachmentzone.ps1">Download Script: Configure-PawAuditAttachmentzone.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAttachmentzone.ps1
Write-Host "Enforcing System Mitigation control: attachment-zone..." -ForegroundColor Cyan

# Set Registry value: SaveZoneInformation
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -Value 2 -Type DWord -Force
Write-Host "    Enforced SaveZoneInformation = 2" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditAttachmentzoneStatus.ps1">Download Script: Get-PawAuditAttachmentzoneStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAttachmentzoneStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: SaveZoneInformation
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.SaveZoneInformation -ne 2) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAttachmentzone.ps1
Write-Host "Enforcing System Mitigation control: attachment-zone..." -ForegroundColor Cyan

# Set Registry value: SaveZoneInformation
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -Value 2 -Type DWord -Force
Write-Host "    Enforced SaveZoneInformation = 2" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7149" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-150" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-150] User Profile: Disable Windows Game DVR for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-161](../../08-endpoints/user-profile/configure-end-up-game-dvr.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-game-dvr.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) are dedicated exclusively to managing Tier 0 Active Directory infrastructure, where administrators interact with domain controllers, certificate templates, and password vaulting solutions. Allowing consumer multimedia recording subsystems (such as Game DVR and the Windows Game Bar) to run on a PAW console creates an intolerable risk of unmonitored administrative session capture and credential exposure.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Game Recording and Broadcasting</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Enables or disables Windows Game Recording and Broadcasting</xhtml:strong> and set it to <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
            <xhtml:li>
              <xhtml:em>(Note: Setting this policy to Disabled enforces AllowGameDVR = 0).</xhtml:em>
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Windows Game DVR on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditGamedvr.ps1">Download Script: Configure-PawAuditGamedvr.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditGamedvr.ps1
Write-Host "Enforcing System Mitigation control: game-dvr..." -ForegroundColor Cyan

# Set Registry value: AllowGameDVR
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord -Force
Write-Host "    Enforced AllowGameDVR = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditGamedvrStatus.ps1">Download Script: Get-PawAuditGamedvrStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditGamedvrStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: AllowGameDVR
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.AllowGameDVR -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditGamedvr.ps1
Write-Host "Enforcing System Mitigation control: game-dvr..." -ForegroundColor Cyan

# Set Registry value: AllowGameDVR
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord -Force
Write-Host "    Enforced AllowGameDVR = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7150" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-151" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-151] User Profile: Restrict Windows Ink Workspace on Lock Screen for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 Active Directory and identity infrastructure administration. <xhtml:em>(For Tier 2 Client Workstations and Member Servers, refer to baseline [REQ-END-162](../../08-endpoints/user-profile/configure-end-up-ink-workspace.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (version 1809 and above), Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/user-profile/configure-paw-up-ink-workspace.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Privileged Access Workstations (PAWs) serve as the dedicated management boundary for Active Directory forest infrastructure. In a PAW environment, the interactive console must remain completely locked against unauthenticated input, secondary application launching, or cached memory viewing when not actively in use by an authenticated administrator.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to Tier 0 Privileged Access Workstations (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Ink Workspace</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Allow Windows Ink Workspace</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> In the </xhtml:em>
              <xhtml:em>Options</xhtml:em>
              <xhtml:em> drop-down menu, select: </xhtml:em>
              <xhtml:em>On, but disallow access above lock</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the dedicated PAW Organizational Unit and enforce replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to restrict Windows Ink Workspace access above the lock screen on the PAW console:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditInkworkspace.ps1">Download Script: Configure-PawAuditInkworkspace.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditInkworkspace.ps1
Write-Host "Enforcing System Mitigation control: ink-workspace..." -ForegroundColor Cyan

# Set Registry value: AllowWindowsInkWorkspace
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -Value 1 -Type DWord -Force
Write-Host "    Enforced AllowWindowsInkWorkspace = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawAuditInkworkspaceStatus.ps1">Download Script: Get-PawAuditInkworkspaceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditInkworkspaceStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: AllowWindowsInkWorkspace
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.AllowWindowsInkWorkspace -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditInkworkspace.ps1
Write-Host "Enforcing System Mitigation control: ink-workspace..." -ForegroundColor Cyan

# Set Registry value: AllowWindowsInkWorkspace
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -Value 1 -Type DWord -Force
Write-Host "    Enforced AllowWindowsInkWorkspace = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7151" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_Services_Hardening">
      <title>Services Hardening</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-037" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-037] Disable Computer Browser Service for PAWs (Browser)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-037](../../08-endpoints/services/disable-browser.md); for Domain Controllers, refer to [REQ-DC-016](../../02-domain-controllers/disable-smbv1.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-browser.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Computer Browser service (<xhtml:code>Browser</xhtml:code>, driven by the kernel driver <xhtml:code>bowser.sys</xhtml:code>) maintains an inventory of network servers and domains across local network segments using unauthenticated NetBIOS over TCP/IP (NetBT) broadcast frames and legacy Server Message Block version 1 (SMBv1) protocol datagrams.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Computer Browser</xhtml:code> (<xhtml:code>Browser</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawBrowser.ps1">Download Script: Configure-DisablePawBrowser.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawBrowser.ps1
# Description: Disables the unnecessary Computer Browser (Browser) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Computer Browser service on PAW..." -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawBrowserStatus.ps1">Download Script: Get-PawBrowserStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawBrowserStatus.ps1
# Description: Audits the startup configuration of Computer Browser (Browser) service on the local PAW system.

Write-Host "--- Auditing Computer Browser (Browser) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawBrowser.ps1
# Description: Disables the unnecessary Computer Browser (Browser) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Computer Browser service on PAW..." -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7037" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-038" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-038] Disable Infrared Monitor Service for PAWs (irmon)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-038](../../08-endpoints/services/disable-irmon.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-irmon.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Infrared Monitor Service (<xhtml:code>irmon</xhtml:code>, hosted within <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>irmon.dll</xhtml:code>) provides management and discovery functions for the legacy Infrared Data Association (IrDA) optical protocol stack and Object Exchange (OBEX) protocol.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Infrared monitor service</xhtml:code> (<xhtml:code>irmon</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawirmon.ps1">Download Script: Configure-DisablePawirmon.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawirmon.ps1
# Description: Disables the unnecessary Infrared monitor service (irmon) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Infrared monitor service service on PAW..." -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawirmonStatus.ps1">Download Script: Get-PawirmonStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawirmonStatus.ps1
# Description: Audits the startup configuration of Infrared monitor service (irmon) service on the local PAW system.

Write-Host "--- Auditing Infrared monitor service (irmon) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawirmon.ps1
# Description: Disables the unnecessary Infrared monitor service (irmon) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Infrared monitor service service on PAW..." -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7038" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-039" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-039] Disable Internet Connection Sharing (ICS) Service for PAWs (SharedAccess)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-039](../../08-endpoints/services/disable-sharedaccess.md); for Domain Controllers, refer to [REQ-DC-044](../../02-domain-controllers/services/disable-sharedaccess.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-sharedaccess.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Internet Connection Sharing service (<xhtml:code>SharedAccess</xhtml:code> / ICS) provides Network Address Translation (NAT), dynamic addressing (embedded DHCP server), and name resolution (DNS proxy) capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Internet Connection Sharing (ICS)</xhtml:code> (<xhtml:code>SharedAccess</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawSharedAccess.ps1">Download Script: Configure-DisablePawSharedAccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service on PAW..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawSharedAccessStatus.ps1">Download Script: Get-PawSharedAccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawSharedAccessStatus.ps1
# Description: Audits the startup configuration of Internet Connection Sharing (ICS) (SharedAccess) service on the local PAW system.

Write-Host "--- Auditing Internet Connection Sharing (ICS) (SharedAccess) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service on PAW..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7039" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-040" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-040] Disable LxssManager Service for PAWs (LxssManager)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-040](../../08-endpoints/services/disable-lxssmanager.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-lxssmanager.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Subsystem for Linux (WSL) service (<xhtml:code>LxssManager</xhtml:code>) manages the lifecycle, execution, and resource allocation of Linux distributions within Windows, utilizing syscall translation or lightweight Hyper-V micro-virtual machines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>LxssManager</xhtml:code> (<xhtml:code>LxssManager</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawLxssManager.ps1">Download Script: Configure-DisablePawLxssManager.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawLxssManager.ps1
# Description: Disables the unnecessary LxssManager (LxssManager) service on the local PAW.

Write-Host "Applying hardening requirement: Disable LxssManager service on PAW..." -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawLxssManagerStatus.ps1">Download Script: Get-PawLxssManagerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawLxssManagerStatus.ps1
# Description: Audits the startup configuration of LxssManager (LxssManager) service on the local PAW system.

Write-Host "--- Auditing LxssManager (LxssManager) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawLxssManager.ps1
# Description: Disables the unnecessary LxssManager (LxssManager) service on the local PAW.

Write-Host "Applying hardening requirement: Disable LxssManager service on PAW..." -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7040" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-041" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-041] Disable Microsoft FTP Service for PAWs (FTPSVC)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-041](../../08-endpoints/services/disable-ftpsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-ftpsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Microsoft FTP Service (<xhtml:code>FTPSVC</xhtml:code>) is an IIS server component that provides File Transfer Protocol (FTP) hosting services over TCP port 21.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Microsoft FTP Service</xhtml:code> (<xhtml:code>FTPSVC</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawFTPSVC.ps1">Download Script: Configure-DisablePawFTPSVC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawFTPSVC.ps1
# Description: Disables the unnecessary Microsoft FTP Service (FTPSVC) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Microsoft FTP Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawFTPSVCStatus.ps1">Download Script: Get-PawFTPSVCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawFTPSVCStatus.ps1
# Description: Audits the startup configuration of Microsoft FTP Service (FTPSVC) service on the local PAW system.

Write-Host "--- Auditing Microsoft FTP Service (FTPSVC) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawFTPSVC.ps1
# Description: Disables the unnecessary Microsoft FTP Service (FTPSVC) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Microsoft FTP Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7041" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-042" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-042] Disable OpenSSH SSH Server Service for PAWs (sshd)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-042](../../08-endpoints/services/disable-sshd.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-sshd.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The OpenSSH SSH Server service (<xhtml:code>sshd</xhtml:code>) provides inbound secure shell access, remote command-line session hosting, and secure file transfer (SFTP/SCP) over TCP port 22.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>OpenSSH SSH Server</xhtml:code> (<xhtml:code>sshd</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawsshd.ps1">Download Script: Configure-DisablePawsshd.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawsshd.ps1
# Description: Disables the unnecessary OpenSSH SSH Server (sshd) service on the local PAW.

Write-Host "Applying hardening requirement: Disable OpenSSH SSH Server service on PAW..." -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawsshdStatus.ps1">Download Script: Get-PawsshdStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawsshdStatus.ps1
# Description: Audits the startup configuration of OpenSSH SSH Server (sshd) service on the local PAW system.

Write-Host "--- Auditing OpenSSH SSH Server (sshd) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawsshd.ps1
# Description: Disables the unnecessary OpenSSH SSH Server (sshd) service on the local PAW.

Write-Host "Applying hardening requirement: Disable OpenSSH SSH Server service on PAW..." -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7042" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-043" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-043] Disable Remote Procedure Call (RPC) Locator Service for PAWs (RpcLocator)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-043](../../08-endpoints/services/disable-rpclocator.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-rpclocator.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Remote Procedure Call (RPC) Locator service (<xhtml:code>RpcLocator</xhtml:code>) manages the legacy RPC name service database, historically used in pre-Windows 2000 architectures to locate RPC server interfaces.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Remote Procedure Call (RPC) Locator</xhtml:code> (<xhtml:code>RpcLocator</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawRpcLocator.ps1">Download Script: Configure-DisablePawRpcLocator.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawRpcLocator.ps1
# Description: Disables the unnecessary Remote Procedure Call (RPC) Locator (RpcLocator) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Remote Procedure Call (RPC) Locator service on PAW..." -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawRpcLocatorStatus.ps1">Download Script: Get-PawRpcLocatorStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawRpcLocatorStatus.ps1
# Description: Audits the startup configuration of Remote Procedure Call (RPC) Locator (RpcLocator) service on the local PAW system.

Write-Host "--- Auditing Remote Procedure Call (RPC) Locator (RpcLocator) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawRpcLocator.ps1
# Description: Disables the unnecessary Remote Procedure Call (RPC) Locator (RpcLocator) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Remote Procedure Call (RPC) Locator service on PAW..." -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7043" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-044" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-044] Disable Routing and Remote Access Service for PAWs (RemoteAccess)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-044](../../08-endpoints/services/disable-remoteaccess.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-remoteaccess.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Routing and Remote Access Service (<xhtml:code>RemoteAccess</xhtml:code> / RRAS) provides software-based packet routing, Network Address Translation (NAT), and incoming VPN server termination capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Routing and Remote Access</xhtml:code> (<xhtml:code>RemoteAccess</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawRemoteAccess.ps1">Download Script: Configure-DisablePawRemoteAccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawRemoteAccess.ps1
# Description: Disables the unnecessary Routing and Remote Access (RemoteAccess) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Routing and Remote Access service on PAW..." -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawRemoteAccessStatus.ps1">Download Script: Get-PawRemoteAccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawRemoteAccessStatus.ps1
# Description: Audits the startup configuration of Routing and Remote Access (RemoteAccess) service on the local PAW system.

Write-Host "--- Auditing Routing and Remote Access (RemoteAccess) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawRemoteAccess.ps1
# Description: Disables the unnecessary Routing and Remote Access (RemoteAccess) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Routing and Remote Access service on PAW..." -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7044" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-045" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-045] Disable Simple TCP/IP Services for PAWs (simptcp)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-045](../../08-endpoints/services/disable-simptcp.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-simptcp.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Simple TCP/IP Services (<xhtml:code>simptcp</xhtml:code>) implement a suite of legacy diagnostic protocols (Echo, Discard, Character Generator, Daytime, and Quote of the Day) operating across 10 distinct TCP and UDP network ports.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Simple TCP/IP Services</xhtml:code> (<xhtml:code>simptcp</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawsimptcp.ps1">Download Script: Configure-DisablePawsimptcp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawsimptcp.ps1
# Description: Disables the unnecessary Simple TCP/IP Services (simptcp) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Simple TCP/IP Services service on PAW..." -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawsimptcpStatus.ps1">Download Script: Get-PawsimptcpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawsimptcpStatus.ps1
# Description: Audits the startup configuration of Simple TCP/IP Services (simptcp) service on the local PAW system.

Write-Host "--- Auditing Simple TCP/IP Services (simptcp) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawsimptcp.ps1
# Description: Disables the unnecessary Simple TCP/IP Services (simptcp) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Simple TCP/IP Services service on PAW..." -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7045" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-046" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-046] Disable Special Administration Console Helper Service for PAWs (sacsvr)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-046](../../08-endpoints/services/disable-sacsvr.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-sacsvr.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Special Administration Console (SAC) Helper service (<xhtml:code>sacsvr</xhtml:code>) facilitates Emergency Management Services (EMS), an out-of-band administrative console subsystem engineered for headless enterprise server hardware to enable text-based diagnostic access over physical or virtual serial (COM) ports.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Special Administration Console Helper</xhtml:code> (<xhtml:code>sacsvr</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawsacsvr.ps1">Download Script: Configure-DisablePawsacsvr.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawsacsvr.ps1
# Description: Disables the unnecessary Special Administration Console Helper (sacsvr) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Special Administration Console Helper service on PAW..." -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawsacsvrStatus.ps1">Download Script: Get-PawsacsvrStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawsacsvrStatus.ps1
# Description: Audits the startup configuration of Special Administration Console Helper (sacsvr) service on the local PAW system.

Write-Host "--- Auditing Special Administration Console Helper (sacsvr) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawsacsvr.ps1
# Description: Disables the unnecessary Special Administration Console Helper (sacsvr) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Special Administration Console Helper service on PAW..." -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7046" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-047" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-047] Disable SSDP Discovery Service for PAWs (SSDPSRV)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-047](../../08-endpoints/services/disable-ssdpsrv.md); for Domain Controllers, refer to [REQ-DC-060](../../02-domain-controllers/services/disable-ssdpsrv.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-ssdpsrv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Simple Service Discovery Protocol (SSDP) Discovery service (<xhtml:code>SSDPSRV</xhtml:code>) listens on UDP port 1900 multicast (<xhtml:code>239.255.255.250</xhtml:code> for IPv4 and <xhtml:code>[FF02::C]</xhtml:code> / <xhtml:code>[FF05::C]</xhtml:code> for IPv6) to discover Universal Plug and Play (UPnP) networked devices such as consumer printers, media renderers, and smart appliances.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>SSDP Discovery</xhtml:code> (<xhtml:code>SSDPSRV</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawSSDPSRV.ps1">Download Script: Configure-DisablePawSSDPSRV.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service on the local PAW.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service on PAW..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawSSDPSRVStatus.ps1">Download Script: Get-PawSSDPSRVStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawSSDPSRVStatus.ps1
# Description: Audits the startup configuration of SSDP Discovery (SSDPSRV) service on the local PAW system.

Write-Host "--- Auditing SSDP Discovery (SSDPSRV) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service on the local PAW.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service on PAW..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7047" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-048" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-048] Disable UPnP Device Host Service for PAWs (upnphost)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-048](../../08-endpoints/services/disable-upnphost.md); for Domain Controllers, refer to [REQ-DC-063](../../02-domain-controllers/services/disable-upnphost.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-upnphost.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The UPnP Device Host service (<xhtml:code>upnphost</xhtml:code>) allows a host to configure, announce, and expose dynamic Universal Plug and Play (UPnP) devices and control points to the local area network over unauthenticated HTTP endpoints.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>UPnP Device Host</xhtml:code> (<xhtml:code>upnphost</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawupnphost.ps1">Download Script: Configure-DisablePawupnphost.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service on the local PAW.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service on PAW..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawupnphostStatus.ps1">Download Script: Get-PawupnphostStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawupnphostStatus.ps1
# Description: Audits the startup configuration of UPnP Device Host (upnphost) service on the local PAW system.

Write-Host "--- Auditing UPnP Device Host (upnphost) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service on the local PAW.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service on PAW..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7048" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-049" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-049] Disable Web Management Service for PAWs (WMSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-049](../../08-endpoints/services/disable-wmsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-wmsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Web Management Service (<xhtml:code>WMSvc</xhtml:code>) enables remote web server management for Internet Information Services (IIS), listening for incoming remote connections over HTTPS TCP port 8172.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Web Management Service</xhtml:code> (<xhtml:code>WMSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawWMSvc.ps1">Download Script: Configure-DisablePawWMSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawWMSvc.ps1
# Description: Disables the unnecessary Web Management Service (WMSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Web Management Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawWMSvcStatus.ps1">Download Script: Get-PawWMSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawWMSvcStatus.ps1
# Description: Audits the startup configuration of Web Management Service (WMSvc) service on the local PAW system.

Write-Host "--- Auditing Web Management Service (WMSvc) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawWMSvc.ps1
# Description: Disables the unnecessary Web Management Service (WMSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Web Management Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7049" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-050" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-050] Disable Windows Media Player Network Sharing Service for PAWs (WMPNetworkSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-050](../../08-endpoints/services/disable-wmpnetworksvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-wmpnetworksvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Media Player Network Sharing Service (<xhtml:code>WMPNetworkSvc</xhtml:code>, hosted by <xhtml:code>wmpnetwk.exe</xhtml:code> or <xhtml:code>svchost.exe</xhtml:code>) shares local Windows Media Player multimedia libraries across the network using Universal Plug and Play (UPnP) and Digital Living Network Alliance (DLNA) protocols.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Windows Media Player Network Sharing Service</xhtml:code> (<xhtml:code>WMPNetworkSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawWMPNetworkSvc.ps1">Download Script: Configure-DisablePawWMPNetworkSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawWMPNetworkSvc.ps1
# Description: Disables the unnecessary Windows Media Player Network Sharing Service (WMPNetworkSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Windows Media Player Network Sharing Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawWMPNetworkSvcStatus.ps1">Download Script: Get-PawWMPNetworkSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawWMPNetworkSvcStatus.ps1
# Description: Audits the startup configuration of Windows Media Player Network Sharing Service (WMPNetworkSvc) service on the local PAW system.

Write-Host "--- Auditing Windows Media Player Network Sharing Service (WMPNetworkSvc) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawWMPNetworkSvc.ps1
# Description: Disables the unnecessary Windows Media Player Network Sharing Service (WMPNetworkSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Windows Media Player Network Sharing Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7050" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-051" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-051] Disable Windows Mobile Hotspot Service for PAWs (icssvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-051](../../08-endpoints/services/disable-icssvc.md); for Domain Controllers, refer to [REQ-DC-072](../../02-domain-controllers/services/disable-icssvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-icssvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Mobile Hotspot Service (<xhtml:code>icssvc</xhtml:code>) manages software-based wireless access point (SoftAP) hosting and network tethering features.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Windows Mobile Hotspot Service</xhtml:code> (<xhtml:code>icssvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawicssvc.ps1">Download Script: Configure-DisablePawicssvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawicssvcStatus.ps1">Download Script: Get-PawicssvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawicssvcStatus.ps1
# Description: Audits the startup configuration of Windows Mobile Hotspot Service (icssvc) service on the local PAW system.

Write-Host "--- Auditing Windows Mobile Hotspot Service (icssvc) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7051" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-052" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-052] Disable World Wide Web Publishing Service for PAWs (W3SVC)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-052](../../08-endpoints/services/disable-w3svc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-w3svc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The World Wide Web Publishing Service (<xhtml:code>W3SVC</xhtml:code>) is the core engine for Internet Information Services (IIS), responsible for managing HTTP/HTTPS listeners, routing requests to <xhtml:code>w3wp.exe</xhtml:code> worker processes, and hosting web applications.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>World Wide Web Publishing Service</xhtml:code> (<xhtml:code>W3SVC</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawW3SVC.ps1">Download Script: Configure-DisablePawW3SVC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawW3SVC.ps1
# Description: Disables the unnecessary World Wide Web Publishing Service (W3SVC) service on the local PAW.

Write-Host "Applying hardening requirement: Disable World Wide Web Publishing Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawW3SVCStatus.ps1">Download Script: Get-PawW3SVCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawW3SVCStatus.ps1
# Description: Audits the startup configuration of World Wide Web Publishing Service (W3SVC) service on the local PAW system.

Write-Host "--- Auditing World Wide Web Publishing Service (W3SVC) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawW3SVC.ps1
# Description: Disables the unnecessary World Wide Web Publishing Service (W3SVC) service on the local PAW.

Write-Host "Applying hardening requirement: Disable World Wide Web Publishing Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7052" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-053" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-053] Disable Xbox Accessory Management Service for PAWs (XboxGipSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-053](../../08-endpoints/services/disable-xboxgipsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-xboxgipsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Accessory Management Service (<xhtml:code>XboxGipSvc</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XboxGipSvc.dll</xhtml:code>) manages Xbox gamepads, wireless gaming dongles, and consumer gaming accessories by interfacing directly with the Xbox Game Input Protocol (GIP) driver stack (<xhtml:code>xboxgip.sys</xhtml:code>).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Accessory Management Service</xhtml:code> (<xhtml:code>XboxGipSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawXboxGipSvc.ps1">Download Script: Configure-DisablePawXboxGipSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawXboxGipSvc.ps1
# Description: Disables the unnecessary Xbox Accessory Management Service (XboxGipSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Accessory Management Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawXboxGipSvcStatus.ps1">Download Script: Get-PawXboxGipSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawXboxGipSvcStatus.ps1
# Description: Audits the startup configuration of Xbox Accessory Management Service (XboxGipSvc) service on the local PAW system.

Write-Host "--- Auditing Xbox Accessory Management Service (XboxGipSvc) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawXboxGipSvc.ps1
# Description: Disables the unnecessary Xbox Accessory Management Service (XboxGipSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Accessory Management Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7053" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-054" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-054] Disable Xbox Live Auth Manager for PAWs (XblAuthManager)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-054](../../08-endpoints/services/disable-xblauthmanager.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-xblauthmanager.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Auth Manager (<xhtml:code>XblAuthManager</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XblAuthManager.dll</xhtml:code>) provides programmatic token brokering and identity authentication services for consumer Microsoft Accounts (MSA) and the Xbox Live ecosystem.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Auth Manager</xhtml:code> (<xhtml:code>XblAuthManager</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawXblAuthManager.ps1">Download Script: Configure-DisablePawXblAuthManager.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service on PAW..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawXblAuthManagerStatus.ps1">Download Script: Get-PawXblAuthManagerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawXblAuthManagerStatus.ps1
# Description: Audits the startup configuration of Xbox Live Auth Manager (XblAuthManager) service on the local PAW system.

Write-Host "--- Auditing Xbox Live Auth Manager (XblAuthManager) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service on PAW..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7054" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-055" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-055] Disable Xbox Live Game Save Service for PAWs (XblGameSave)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-055](../../08-endpoints/services/disable-xblgamesave.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-xblgamesave.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Game Save Service (<xhtml:code>XblGameSave</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XblGameSave.dll</xhtml:code>) performs background synchronization of game save containers and application state to Microsoft Xbox Live consumer cloud infrastructure.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Game Save</xhtml:code> (<xhtml:code>XblGameSave</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawXblGameSave.ps1">Download Script: Configure-DisablePawXblGameSave.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service on PAW..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawXblGameSaveStatus.ps1">Download Script: Get-PawXblGameSaveStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawXblGameSaveStatus.ps1
# Description: Audits the startup configuration of Xbox Live Game Save (XblGameSave) service on the local PAW system.

Write-Host "--- Auditing Xbox Live Game Save (XblGameSave) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service on PAW..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7055" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-056" severity="medium" weight="10.0" selected="false">
        <title>[REQ-PAW-056] Disable Xbox Live Networking Service for PAWs (XboxNetApiSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For Tier 2 client workstations and member servers, refer to baseline [REQ-END-056](../../08-endpoints/services/disable-xboxnetapisvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-xboxnetapisvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Networking Service (<xhtml:code>XboxNetApiSvc</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XboxNetApiSvc.dll</xhtml:code>) provides network interface abstraction, peer-to-peer session negotiation, and Teredo NAT traversal tunneling for consumer gaming applications.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Networking Service</xhtml:code> (<xhtml:code>XboxNetApiSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawXboxNetApiSvc.ps1">Download Script: Configure-DisablePawXboxNetApiSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawXboxNetApiSvc.ps1
# Description: Disables the unnecessary Xbox Live Networking Service (XboxNetApiSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Networking Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawXboxNetApiSvcStatus.ps1">Download Script: Get-PawXboxNetApiSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawXboxNetApiSvcStatus.ps1
# Description: Audits the startup configuration of Xbox Live Networking Service (XboxNetApiSvc) service on the local PAW system.

Write-Host "--- Auditing Xbox Live Networking Service (XboxNetApiSvc) Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawXboxNetApiSvc.ps1
# Description: Disables the unnecessary Xbox Live Networking Service (XboxNetApiSvc) service on the local PAW.

Write-Host "Applying hardening requirement: Disable Xbox Live Networking Service service on PAW..." -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7056" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-166" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-166] Disable WebClient Service for PAWs (WebClient)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs) used for Tier 0 directory administration. <xhtml:em>(For standard client workstations and member servers, refer to baseline [REQ-END-177](../../08-endpoints/services/disable-webclient.md); for Domain Controllers, refer to [REQ-DC-146](../../02-domain-controllers/services/disable-webclient.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (all supported builds) and Windows 11 Enterprise.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/services/disable-webclient.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The WebClient service (<xhtml:code>WebClient</xhtml:code>, driven by <xhtml:code>davclnt.sys</xhtml:code>) handles Web Distributed Authoring and Versioning (WebDAV) file requests over HTTP and HTTPS.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the PAW GPO (e.g., <xhtml:code>GPO_Hardening_PAW</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>WebClient</xhtml:code>, double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisablePawWebClient.ps1">Download Script: Configure-DisablePawWebClient.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisablePawWebClient.ps1
# Description: Disables the unnecessary WebClient service on the local PAW system.

Write-Host "Applying hardening requirement: Disable WebClient service on PAW..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup configuration of the WebClient service on the PAW:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-PawWebClientStatus.ps1">Download Script: Get-PawWebClientStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawWebClientStatus.ps1
# Description: Audits the startup configuration of the WebClient service on the local PAW system.

Write-Host "--- Auditing WebClient Service on PAW ---" -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisablePawWebClient.ps1
# Description: Disables the unnecessary WebClient service on the local PAW system.

Write-Host "Applying hardening requirement: Disable WebClient service on PAW..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7166" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_7__Privileged_Access_Workstations__PAWs__Hardening_Advanced_Security_Audit_Policies">
      <title>Advanced Security Audit Policies</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-130" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-130] Audit Policy: Advanced Audit Policy Overrides for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-audit-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing advanced audit policy overrides prevents legacy category settings from overriding refined subcategory policies, and disabling verbose Kerberos logging ensures that event logs are not flooded with diagnostic events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\System\CurrentControlSet\Control\Lsa\ SCENoApplyLegacyAuditPolicy</xhtml:code> = <xhtml:code>1</xhtml:code> (DWord)</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters\ LogLevel</xhtml:code> = <xhtml:code>0</xhtml:code> (DWord)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAuditoverride.ps1">Download Script: Configure-PawAuditAuditoverride.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditAuditoverrideStatus.ps1">Download Script: Get-PawAuditAuditoverrideStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAuditoverrideStatus.ps1
$script:Vulnerable = $false

# Audit Registry: SCENoApplyLegacyAuditPolicy
$RegVal = Get-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.SCENoApplyLegacyAuditPolicy -ne 1) {
    $script:Vulnerable = $true
}

# Audit Registry: LogLevel
$RegVal = Get-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LogLevel -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7130" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-131" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-131] Audit Policy: Account Logon Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-account-logon.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account logon events captures authentication requests processed by the local system or the workstation, which is critical for identifying Kerberoasting, NTLM relaying, and brute-force attempts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Credential Validation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAccountlogon.ps1">Download Script: Configure-PawAuditAccountlogon.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditAccountlogonStatus.ps1">Download Script: Get-PawAuditAccountlogonStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAccountlogonStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Credential Validation
$RawOutput = auditpol.exe /get /subcategory:"Credential Validation" /r
if ($RawOutput -notmatch ",Credential Validation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7131" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-132" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-132] Audit Policy: Account Management Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-account-management.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account management logs security principal modifications (creations, deletions, password resets, group modifications) to detect privilege escalation attempts on domain or local administrative groups.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>User Account Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security Group Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Computer Account Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Account Management Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditAccountmanagement.ps1">Download Script: Configure-PawAuditAccountmanagement.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Computer Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Computer Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Computer Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Computer Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditAccountmanagementStatus.ps1">Download Script: Get-PawAuditAccountmanagementStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditAccountmanagementStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: User Account Management
$RawOutput = auditpol.exe /get /subcategory:"User Account Management" /r
if ($RawOutput -notmatch ",User Account Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security Group Management
$RawOutput = auditpol.exe /get /subcategory:"Security Group Management" /r
if ($RawOutput -notmatch ",Security Group Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Computer Account Management
$RawOutput = auditpol.exe /get /subcategory:"Computer Account Management" /r
if ($RawOutput -notmatch ",Computer Account Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Account Management Events
$RawOutput = auditpol.exe /get /subcategory:"Other Account Management Events" /r
if ($RawOutput -notmatch ",Other Account Management Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Computer Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Computer Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Computer Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Computer Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7132" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-133" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-133] Audit Policy: Detailed Tracking Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-detailed-tracking.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Detailed tracking records process creations and device arrivals to ensure EDR/SIEM visibility into executable command lines and hardware plug events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Process Creation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>DPAPI Activity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>PNP Activity</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditDetailedtracking.ps1">Download Script: Configure-PawAuditDetailedtracking.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditDetailedtrackingStatus.ps1">Download Script: Get-PawAuditDetailedtrackingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditDetailedtrackingStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Process Creation
$RawOutput = auditpol.exe /get /subcategory:"Process Creation" /r
if ($RawOutput -notmatch ",Process Creation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: DPAPI Activity
$RawOutput = auditpol.exe /get /subcategory:"DPAPI Activity" /r
if ($RawOutput -notmatch ",DPAPI Activity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: PNP Activity
$RawOutput = auditpol.exe /get /subcategory:"PNP Activity" /r
if ($RawOutput -notmatch ",PNP Activity,.*,Success") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7133" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-135" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-135] Audit Policy: Logon and Logoff Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-logon-logoff.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing logon/logoff events monitors administrative session states, special elevations, and failed logon attempts, which is critical for finding unauthorized remote access or lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logoff</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Special Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Account Lockout</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Logon/Logoff Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditLogonlogoff.ps1">Download Script: Configure-PawAuditLogonlogoff.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditLogonlogoffStatus.ps1">Download Script: Get-PawAuditLogonlogoffStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditLogonlogoffStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Logon
$RawOutput = auditpol.exe /get /subcategory:"Logon" /r
if ($RawOutput -notmatch ",Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Logoff
$RawOutput = auditpol.exe /get /subcategory:"Logoff" /r
if ($RawOutput -notmatch ",Logoff,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Special Logon
$RawOutput = auditpol.exe /get /subcategory:"Special Logon" /r
if ($RawOutput -notmatch ",Special Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Account Lockout
$RawOutput = auditpol.exe /get /subcategory:"Account Lockout" /r
if ($RawOutput -notmatch ",Account Lockout,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Logon/Logoff Events
$RawOutput = auditpol.exe /get /subcategory:"Other Logon/Logoff Events" /r
if ($RawOutput -notmatch ",Other Logon/Logoff Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7135" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-136" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-136] Audit Policy: Object Access Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-object-access.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing object access (files, registry keys, and shares) helps monitor unauthorized modifications to system configuration files and access to restricted shares.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Handle Manipulation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Registry</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>File Share</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Detailed File Share</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Object Access Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditObjectaccess.ps1">Download Script: Configure-PawAuditObjectaccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Object Access Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Object Access Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Object Access Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Object Access Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditObjectaccessStatus.ps1">Download Script: Get-PawAuditObjectaccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditObjectaccessStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Handle Manipulation
$RawOutput = auditpol.exe /get /subcategory:"Handle Manipulation" /r
if ($RawOutput -notmatch ",Handle Manipulation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Registry
$RawOutput = auditpol.exe /get /subcategory:"Registry" /r
if ($RawOutput -notmatch ",Registry,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: File Share
$RawOutput = auditpol.exe /get /subcategory:"File Share" /r
if ($RawOutput -notmatch ",File Share,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Detailed File Share
$RawOutput = auditpol.exe /get /subcategory:"Detailed File Share" /r
if ($RawOutput -notmatch ",Detailed File Share,.*,Failure") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Object Access Events
$RawOutput = auditpol.exe /get /subcategory:"Other Object Access Events" /r
if ($RawOutput -notmatch ",Other Object Access Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Object Access Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Object Access Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Object Access Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Object Access Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7136" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-137" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-137] Audit Policy: Policy Change Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-policy-change.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing policy changes tracks attempts to modify authorization policies, auditing configuration changes, or firewall rule alterations to hide adversarial tracks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authentication Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authorization Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>MPSSVC Rule-Level Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Policy Change Events</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditPolicychange.ps1">Download Script: Configure-PawAuditPolicychange.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditPolicychangeStatus.ps1">Download Script: Get-PawAuditPolicychangeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditPolicychangeStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Policy Change" /r
if ($RawOutput -notmatch ",Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authentication Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authentication Policy Change" /r
if ($RawOutput -notmatch ",Authentication Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authorization Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authorization Policy Change" /r
if ($RawOutput -notmatch ",Authorization Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: MPSSVC Rule-Level Policy Change
$RawOutput = auditpol.exe /get /subcategory:"MPSSVC Rule-Level Policy Change" /r
if ($RawOutput -notmatch ",MPSSVC Rule-Level Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Policy Change Events
$RawOutput = auditpol.exe /get /subcategory:"Other Policy Change Events" /r
if ($RawOutput -notmatch ",Other Policy Change Events,.*,Failure") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7137" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-138" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-138] Audit Policy: Privilege Use Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-privilege-use.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing sensitive privilege use logs attempts by processes or users to exercise rights like ActAsPartOfTypeOperatingSystem or LoadDrivers, identifying potential privilege escalations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Sensitive Privilege Use</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditPrivilegeuse.ps1">Download Script: Configure-PawAuditPrivilegeuse.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditPrivilegeuseStatus.ps1">Download Script: Get-PawAuditPrivilegeuseStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditPrivilegeuseStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Sensitive Privilege Use
$RawOutput = auditpol.exe /get /subcategory:"Sensitive Privilege Use" /r
if ($RawOutput -notmatch ",Sensitive Privilege Use,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7138" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-PAW-139" severity="high" weight="10.0" selected="false">
        <title>[REQ-PAW-139] Audit Policy: System Events Auditing for PAWs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Privileged Access Workstations (PAWs)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>07-paws/audit-policy/configure-paw-audit-system-events.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing system security extensions, integrity violations, and driver arrivals monitors boot health and tampering of host security services.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>IPsec Driver</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other System Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security State Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security System Extension</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>System Integrity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-PawAuditSystemevents.ps1">Download Script: Configure-PawAuditSystemevents.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-PawAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: IPsec Driver
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"IPsec Driver`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory IPsec Driver to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory IPsec Driver. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-PawAuditSystemeventsStatus.ps1">Download Script: Get-PawAuditSystemeventsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-PawAuditSystemeventsStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: IPsec Driver
$RawOutput = auditpol.exe /get /subcategory:"IPsec Driver" /r
if ($RawOutput -notmatch ",IPsec Driver,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other System Events
$RawOutput = auditpol.exe /get /subcategory:"Other System Events" /r
if ($RawOutput -notmatch ",Other System Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security State Change
$RawOutput = auditpol.exe /get /subcategory:"Security State Change" /r
if ($RawOutput -notmatch ",Security State Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security System Extension
$RawOutput = auditpol.exe /get /subcategory:"Security System Extension" /r
if ($RawOutput -notmatch ",Security System Extension,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: System Integrity
$RawOutput = auditpol.exe /get /subcategory:"System Integrity" /r
if ($RawOutput -notmatch ",System Integrity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-PawAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: IPsec Driver
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"IPsec Driver`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory IPsec Driver to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory IPsec Driver. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:7139" />
        </check>
      </Rule>
    </Group>
  </Group>
  <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening">
    <title>Module 8: Endpoint Hardening</title>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-001" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-001] Harden Network Parameters and Disable Legacy Name Resolution</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/harden-network-and-name-resolution.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Legacy name resolution protocols and insecure default network configurations are heavily targeted by attackers for credential harvesting and man-in-the-middle (MitM) positioning:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Legacy Name Resolution (LLMNR / NetBIOS)</xhtml:strong>: LLMNR and NBT-NS serve as fallback protocols when DNS resolution fails. When a host queries an unresolvable name, it broadcasts requests over the local subnet. An attacker can spoof responses (e.g., using Responder) to capture NTLMv2 hashes or perform authentication relay attacks. NetBIOS name release requests can be forged to disrupt local names unless protected.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>NetBIOS Node Type and Name Release</xhtml:strong>: Setting the Node Type to P-node (point-to-point, value 2) disables broadcast resolution fallbacks. Enabling name release protection (<xhtml:code>NoNameReleaseOnDemand</xhtml:code>) prevents attackers from spoofing name release requests to deregister local names.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>ICMP Redirects</xhtml:strong>: ICMP redirect packets can be used by an attacker on the same subnet to dynamically redirect routing for specific hosts through the attacker's machine, enabling full MitM packet sniffing and modification. Disabling ICMP redirects prevents this vector.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>IP Source Routing</xhtml:strong>: Source routing allows a sender to specify the exact network path a packet should follow. This is commonly abused to bypass firewall routing rules or establish communication paths that violate network segment isolation.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Default IPv6 DNS Servers</xhtml:strong>: Disabling default IPv6 DNS servers prevents automated fallback to unauthenticated, dynamic local IPv6 DNS servers advertised by rogue routers or malicious tools (like mitm6), which would otherwise redirect query traffic and coerce NTLM or Kerberos authentication.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Web Proxy Auto-Discovery (WPAD)</xhtml:strong>: Disabling WPAD removes another name resolution mechanism that Responder exploits to harvest credentials. By disabling the <xhtml:code>WinHttpAutoProxySvc</xhtml:code> service and configuring <xhtml:code>WpadOverride = 1</xhtml:code>, the workstation is protected from rogue web proxy configurations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Restrict Net Session Enumeration (NetCease)</xhtml:strong>: By default, any authenticated domain user can query session information from remote hosts. Attackers utilize session enumeration to locate high-privileged user sessions (e.g., Domain Admins) across the network. Hardening the <xhtml:code>SrvsvcSessionInfo</xhtml:code> default security descriptor blocks this remote reconnaissance.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Configure DNS Client Settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the target endpoints GPO.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\DNS Client</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off Multicast Name Resolution` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Configure multicast DNS (mDNS) protocol` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off default IPv6 DNS Servers` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Configure Network Connections Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\Network Connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit use of Internet Connection Sharing on your DNS domain network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit installation and configuration of Network Bridge on your DNS domain network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Require domain users to elevate when setting a network's location` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Configure Windows Connection Manager Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\Windows Connection Manager</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Minimize the number of simultaneous connections to the Internet or a Windows Domain` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>3 = Prevent Wi-Fi when on Ethernet</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Prohibit connection to non-domain networks when connected to domain authenticated network` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 4: Configure WLAN Settings (WiFi Sense)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Network\WLAN Service\WLAN Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 5: Configure Spooler and HTTP Printing Policies</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off downloading of print drivers over HTTP` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn off printing over HTTP` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 6: Configure Network Access Security settings</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Network access: Restrict anonymous access to Named Pipes and Shares` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 7: Disable WinHTTP WPAD Service</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>In the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Scroll to <xhtml:strong>WinHTTP Web Proxy Auto-Discovery Service</xhtml:strong>, select <xhtml:strong>Define this service setting</xhtml:strong>, and set the service startup mode to <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 8: Configure Registry Network settings via GPO Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Under the target GPO, navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> and select <xhtml:strong>New -&gt; Registry Item</xhtml:strong> for each of the following:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>NetBIOS Name Release Protection</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Netbt\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>NoNameReleaseOnDemand</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>NetBIOS P-Node Type</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Netbt\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>NodeType</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable ICMP Redirects</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>EnableICMPRedirect</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>0</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable IP Source Routing (IPv4)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>DisableIPSourceRouting</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable IP Source Routing (IPv6)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>DisableIPSourceRouting</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Disable WPAD Override (User Preference)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>WpadOverride</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Restrict Net Session Enumeration (NetCease SDDL)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Action</xhtml:strong>: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Key Path</xhtml:strong>: <xhtml:code>SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Name</xhtml:strong>: <xhtml:code>SrvsvcSessionInfo</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Type</xhtml:strong>: <xhtml:code>REG_BINARY</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Value Data</xhtml:strong>: Generate via SDDL <xhtml:code>D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:h4>Step 9: Disable NetBIOS (via DHCP Scope Options)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>DHCP Management Console</xhtml:strong> (<xhtml:code>dhcpmgmt.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Under Scope Options, select <xhtml:strong>Configure Options</xhtml:strong>.</xhtml:li>
          <xhtml:li>Add <xhtml:strong>Option 043 (Vendor Specific Info)</xhtml:strong> and set the NetBIOS over TCP/IP value to <xhtml:code>0x2</xhtml:code> (Disable NetBIOS over TCP/IP).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to disable legacy resolution and enforce secure TCP/IP registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-NetworkHardeningSettings.ps1">Download Script: Set-NetworkHardeningSettings.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-NetworkHardeningSettings.ps1
# Description: Configures local registry keys to disable LLMNR/NetBIOS, harden TCP/IP stack, prevent dual-homing, block hotspot auto-connect, print driver web downloads, HTTP printing, and limit anonymous share access.

Write-Host "Applying network and name resolution hardening..." -ForegroundColor Cyan

# Helper to configure registry keys
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}

# 1. Disable LLMNR, mDNS, and default IPv6 DNS Servers
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnableMulticast" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnablemDNS" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "DisableIPv6DefaultDnsServers" 1
Write-Host "[+] LLMNR (Multicast Name Resolution), mDNS, and default IPv6 DNS Servers disabled." -ForegroundColor Green

# 2. Configure NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
if (-not (Test-Path $NetbtPath)) {
    New-Item -Path $NetbtPath -Force | Out-Null
}
Set-ItemProperty -Path $NetbtPath -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord
Set-ItemProperty -Path $NetbtPath -Name "NodeType" -Value 2 -Type DWord
Write-Host "[+] NetBIOS name release protection and P-node type configured." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all active adapters
Write-Host "[+] Disabling NetBIOS on all active network adapters..." -ForegroundColor Gray
$Adapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue | Where-Object { $_.IPEnabled -eq $true }
if ($Adapters) {
    foreach ($Adapter in $Adapters) {
        Invoke-CimMethod -InputObject $Adapter -MethodName SetTCPIPNetBIOS -Arguments @{ TcpipNetbiosOptions = 2 } | Out-Null
    }
    Write-Host "    NetBIOS disabled on active network interfaces." -ForegroundColor Green
}

# 4. Harden TCP/IP Parameters
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "EnableICMPRedirect" 0
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv4 TCP/IP parameter redirects and source routing disabled." -ForegroundColor Green

Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv6 TCP/IP parameter source routing disabled." -ForegroundColor Green

# 5. Prevent Network Connection Sharing and Dual-Homing Bridging
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_ShowSharedAccessUI" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_AllowNetBridge_NLA" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_StdDomainUserSetLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fMinimizeConnections" 3
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fBlockNonDomain" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config" "AutoConnectAllowedOEM" 0
Write-Host "[+] Network connections, sharing, bridging, elevation, and hotspot settings configured." -ForegroundColor Green

# 6. Printing Spooler Web Downloads and HTTP printing block
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableWebPnPDownload" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Write-Host "[+] Printing spooler HTTP and Web service options disabled." -ForegroundColor Green

# 7. Restrict anonymous access to SAM and Named Pipes/Shares
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" "RestrictNullSessAccess" 1
Write-Host "[+] Anonymous null session share access restricted." -ForegroundColor Green

# 8. Disable WPAD
Write-Host "[+] Disabling WinHTTP Auto-Proxy service..." -ForegroundColor Gray
Set-Service -Name "WinHttpAutoProxySvc" -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name "WinHttpAutoProxySvc" -Force -ErrorAction SilentlyContinue

$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
if (-not (Test-Path $WpadPath)) {
    New-Item -Path $WpadPath -Force | Out-Null
}
Set-ItemProperty -Path $WpadPath -Name "WpadOverride" -Value 1 -Type DWord -Force
Write-Host "[+] WPAD auto-detection disabled in user preferences registry." -ForegroundColor Green

# 9. Restrict Net Session Enumeration (NetCease SDDL)
Write-Host "[+] Restricting Net Session Enumeration..." -ForegroundColor Gray
try {
    $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)")
    $BinaryForm = New-Object byte[] $SD.BinaryLength
    $SD.GetBinaryForm($BinaryForm, 0)
    $LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
    if (-not (Test-Path $LanmanSecPath)) {
        New-Item -Path $LanmanSecPath -Force | Out-Null
    }
    Set-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -Value $BinaryForm -Type Binary -Force
    Write-Host "[+] Net Session Enumeration restricted to Admins/Operators/Power Users." -ForegroundColor Green
} catch {
    Write-Error "    Failed to apply Net Session Enumeration restrictions: $($_.Exception.Message)"
}

Write-Host "Network and name resolution hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the network and name resolution status:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-NetworkHardeningStatus.ps1">Download Script: Test-NetworkHardeningStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-NetworkHardeningStatus.ps1
# Description: Audits LLMNR, NetBIOS parameters, NetBIOS adapter state, TCP/IP parameters, and STIG print / network connection options.

Write-Host "--- Auditing Network and Name Resolution Baseline ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to audit registry properties
function Test-RegistryValue ($path, $name, $expectedValue) {
    $val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    $color = "Red"
    if ($actual -eq $expectedValue) {
        $color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expectedValue')" -ForegroundColor $color
}


# 1. Audit LLMNR, mDNS, and default IPv6 DNS Servers
$DnsPath = "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient"
Test-RegistryValue $DnsPath "EnableMulticast" 0
Test-RegistryValue $DnsPath "EnablemDNS" 0
Test-RegistryValue $DnsPath "DisableIPv6DefaultDnsServers" 1

# 2. Audit NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
Test-RegistryValue $NetbtPath "NoNameReleaseOnDemand" 1
Test-RegistryValue $NetbtPath "NodeType" 2

# 3. Audit TCP/IP Parameters
$TcpipPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
Test-RegistryValue $TcpipPath "EnableICMPRedirect" 0
Test-RegistryValue $TcpipPath "DisableIPSourceRouting" 2

$Tcpip6Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
Test-RegistryValue $Tcpip6Path "DisableIPSourceRouting" 2

# 4. Audit Connection Sharing &amp; Dual-Homing Settings
$NetConnPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections"
Test-RegistryValue $NetConnPath "NC_ShowSharedAccessUI" 0
Test-RegistryValue $NetConnPath "NC_AllowNetBridge_NLA" 0
Test-RegistryValue $NetConnPath "NC_StdDomainUserSetLocation" 1

$WcmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy"
Test-RegistryValue $WcmPath "fMinimizeConnections" 3
Test-RegistryValue $WcmPath "fBlockNonDomain" 1

$WifiPath = "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config"
Test-RegistryValue $WifiPath "AutoConnectAllowedOEM" 0

# 5. Audit HTTP Print Options
$PrinterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
Test-RegistryValue $PrinterPath "DisableWebPnPDownload" 1
Test-RegistryValue $PrinterPath "DisableHTTPPrinting" 1

# 6. Audit Null Session Share Restrict
$ServerPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
Test-RegistryValue $ServerPath "RestrictNullSessAccess" 1

# 7. Audit WPAD Service and Registry Override
$WpadSvc = Get-Service -Name "WinHttpAutoProxySvc" -ErrorAction SilentlyContinue
if ($null -ne $WpadSvc) {
    if ($WpadSvc.StartType -eq "Disabled") {
        Write-Host "    - WPAD Service State: Disabled (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: WPAD Service StartType is $($WpadSvc.StartType) (Expected: Disabled)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}
$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
Test-RegistryValue $WpadPath "WpadOverride" 1

# 8. Audit Net Session Enumeration (NetCease)
$LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
if (Test-Path $LanmanSecPath) {
    $SrvsvcSessionInfo = (Get-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -ErrorAction SilentlyContinue).SrvsvcSessionInfo
    if ($null -ne $SrvsvcSessionInfo) {
        try {
            $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, $SrvsvcSessionInfo, 0)
            $Sddl = $SD.GetSddlForm("Dacl")
            if ($Sddl -eq "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)") {
                Write-Host "    - Net Session Enumeration Security Descriptor: Hardened (Secure)" -ForegroundColor Green
            } else {
                Write-Host "    - VULNERABLE: Net Session Enumeration Security Descriptor is '$Sddl' (Expected: 'D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)')" -ForegroundColor Red
                $script:Vulnerable = $true
            }
        } catch {
            Write-Host "    - VULNERABLE: Failed to parse Net Session Enumeration security descriptor." -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: SrvsvcSessionInfo registry value not found." -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - VULNERABLE: LanmanServer\DefaultSecurity path not found." -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-NetworkHardeningSettings.ps1
# Description: Configures local registry keys to disable LLMNR/NetBIOS, harden TCP/IP stack, prevent dual-homing, block hotspot auto-connect, print driver web downloads, HTTP printing, and limit anonymous share access.

Write-Host "Applying network and name resolution hardening..." -ForegroundColor Cyan

# Helper to configure registry keys
function Set-RegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$path,
        [string]$name,
        [int]$value
    )
    if ($PSCmdlet.ShouldProcess($path, "Set registry DWORD value $name to $value")) {
        $parent = Split-Path -Path $path
        if (-not (Test-Path $parent)) {
            New-Item -Path $parent -Force | Out-Null
        }
        if (-not (Test-Path $path)) {
            New-Item -Path $path -Force | Out-Null
        }
        Set-ItemProperty -Path $path -Name $name -Value $value -Type DWord -Force
    }
}

# 1. Disable LLMNR, mDNS, and default IPv6 DNS Servers
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnableMulticast" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "EnablemDNS" 0
Set-RegDWord "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" "DisableIPv6DefaultDnsServers" 1
Write-Host "[+] LLMNR (Multicast Name Resolution), mDNS, and default IPv6 DNS Servers disabled." -ForegroundColor Green

# 2. Configure NetBIOS Parameters
$NetbtPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters"
if (-not (Test-Path $NetbtPath)) {
    New-Item -Path $NetbtPath -Force | Out-Null
}
Set-ItemProperty -Path $NetbtPath -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord
Set-ItemProperty -Path $NetbtPath -Name "NodeType" -Value 2 -Type DWord
Write-Host "[+] NetBIOS name release protection and P-node type configured." -ForegroundColor Green

# 3. Disable NetBIOS over TCP/IP on all active adapters
Write-Host "[+] Disabling NetBIOS on all active network adapters..." -ForegroundColor Gray
$Adapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue | Where-Object { $_.IPEnabled -eq $true }
if ($Adapters) {
    foreach ($Adapter in $Adapters) {
        Invoke-CimMethod -InputObject $Adapter -MethodName SetTCPIPNetBIOS -Arguments @{ TcpipNetbiosOptions = 2 } | Out-Null
    }
    Write-Host "    NetBIOS disabled on active network interfaces." -ForegroundColor Green
}

# 4. Harden TCP/IP Parameters
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "EnableICMPRedirect" 0
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv4 TCP/IP parameter redirects and source routing disabled." -ForegroundColor Green

Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" "DisableIPSourceRouting" 2
Write-Host "[+] IPv6 TCP/IP parameter source routing disabled." -ForegroundColor Green

# 5. Prevent Network Connection Sharing and Dual-Homing Bridging
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_ShowSharedAccessUI" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_AllowNetBridge_NLA" 0
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" "NC_StdDomainUserSetLocation" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fMinimizeConnections" 3
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" "fBlockNonDomain" 1
Set-RegDWord "HKLM:\SOFTWARE\Microsoft\wcmsvc\wifinetworkmanager\config" "AutoConnectAllowedOEM" 0
Write-Host "[+] Network connections, sharing, bridging, elevation, and hotspot settings configured." -ForegroundColor Green

# 6. Printing Spooler Web Downloads and HTTP printing block
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableWebPnPDownload" 1
Set-RegDWord "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" "DisableHTTPPrinting" 1
Write-Host "[+] Printing spooler HTTP and Web service options disabled." -ForegroundColor Green

# 7. Restrict anonymous access to SAM and Named Pipes/Shares
Set-RegDWord "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" "RestrictNullSessAccess" 1
Write-Host "[+] Anonymous null session share access restricted." -ForegroundColor Green

# 8. Disable WPAD
Write-Host "[+] Disabling WinHTTP Auto-Proxy service..." -ForegroundColor Gray
Set-Service -Name "WinHttpAutoProxySvc" -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name "WinHttpAutoProxySvc" -Force -ErrorAction SilentlyContinue

$WpadPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"
if (-not (Test-Path $WpadPath)) {
    New-Item -Path $WpadPath -Force | Out-Null
}
Set-ItemProperty -Path $WpadPath -Name "WpadOverride" -Value 1 -Type DWord -Force
Write-Host "[+] WPAD auto-detection disabled in user preferences registry." -ForegroundColor Green

# 9. Restrict Net Session Enumeration (NetCease SDDL)
Write-Host "[+] Restricting Net Session Enumeration..." -ForegroundColor Gray
try {
    $SD = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, "D:(A;;CC;;;BA)(A;;CC;;;SO)(A;;CC;;;PU)")
    $BinaryForm = New-Object byte[] $SD.BinaryLength
    $SD.GetBinaryForm($BinaryForm, 0)
    $LanmanSecPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity"
    if (-not (Test-Path $LanmanSecPath)) {
        New-Item -Path $LanmanSecPath -Force | Out-Null
    }
    Set-ItemProperty -Path $LanmanSecPath -Name "SrvsvcSessionInfo" -Value $BinaryForm -Type Binary -Force
    Write-Host "[+] Net Session Enumeration restricted to Admins/Operators/Power Users." -ForegroundColor Green
} catch {
    Write-Error "    Failed to apply Net Session Enumeration restrictions: $($_.Exception.Message)"
}

Write-Host "Network and name resolution hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8001" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-002" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-002] Configure User Account Control Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-uac-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>User Account Control (UAC) is a fundamental defense mechanism in Windows. It limits the privilege levels of running applications, executing administrative actions with standard user tokens unless elevated privileges are explicitly approved.</xhtml:p>
        <xhtml:p>Hardening UAC settings ensures: 1. <xhtml:strong>Secure Desktop Enforcement</xhtml:strong>: The elevation prompt is displayed on a separate, secure desktop environment that isolated system threads run on. This prevents third-party malware running in user space from intercepting credentials or programmatically clicking "Yes" to elevate itself. 2. <xhtml:strong>Auto-Denial of Standard User Elevation</xhtml:strong>: Standard users should not be allowed to request elevation. If a standard user triggers a task requiring administrative rights, the prompt should auto-deny rather than requesting an administrator password, preventing users from attempting to bypass controls or exposing local admin passwords on a non-secure user terminal. 3. <xhtml:strong>Admin Approval Mode</xhtml:strong>: Forcing built-in administrators to run in Admin Approval Mode ensures that even administrative users do not run web browsers or document editors with administrative tokens by default. 4. <xhtml:strong>Sudo Command Control</xhtml:strong>: The <xhtml:code>sudo</xhtml:code> command introduced in Windows 11 (24H2) allows users to run elevated commands from an unelevated console. Leaving this feature unconfigured or allowing execution within the current console session can expose elevated processes to command injection or token interception in the same console session. Restricting <xhtml:code>sudo</xhtml:code> to opening a new elevated window (<xhtml:code>1</xhtml:code>) or disabling it entirely (<xhtml:code>0</xhtml:code>) mitigates session hijacking risks. 5. <xhtml:strong>Network UAC Restrictions (`LocalAccountTokenFilterPolicy`)</xhtml:strong>: Restricting the elevation of local accounts during network logons prevents lateral movement. When set to <xhtml:code>0</xhtml:code>, local accounts (except for the built-in Administrator RID 500 account) connecting remotely via network shares or administrative interfaces cannot obtain administrative tokens, neutralizing pass-the-hash attacks using secondary local administrative accounts. 6. <xhtml:strong>Installer Detection (`EnableInstallDetection`)</xhtml:strong>: Detecting installer program behavior prevents silent software execution. When enabled, any execution of an install file or setup program by standard users or administrators triggers a UAC elevation prompt, preventing unauthorized silent program deployments. 7. <xhtml:strong>UAC Virtualization (`EnableVirtualization`)</xhtml:strong>: Virtualizing writes redirection keeps the operating system directory space clean. It redirects legacy application registry and file writes targeting system folders (like <xhtml:code>Program Files</xhtml:code> or <xhtml:code>System32</xhtml:code>) to user-profile-specific folders, allowing legacy applications to run without requiring administrative rights.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode` -&gt; </xhtml:em>
            <xhtml:em>Prompt for credentials on the secure desktop</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Behavior of the elevation prompt for standard users` -&gt; </xhtml:em>
            <xhtml:em>Automatically deny elevation requests</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Run all administrators in Admin Approval Mode` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Switch to the secure desktop when prompting for elevation` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Detect application installations and prompt for elevation` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `User Account Control: Virtualize file and registry write failures to per-user locations` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Since the UAC network restrictions policy is not directly exposed in standard GPO security templates, deploy the registry setting via GPO Preferences:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Create a new Registry Item:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LocalAccountTokenFilterPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Configure the behavior of the sudo command` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with options set to </xhtml:em>
            <xhtml:em>Force a new elevated window</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure maximum security parameters for UAC in the system registry.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-UACPolicies.ps1">Download Script: Configure-UACPolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-UACPolicies.ps1
# Enforces hardened User Account Control (UAC) registry configuration values including network restrictions, installer detection, and virtualization.

Write-Host "--- Hardening User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

# ConsentPromptBehaviorAdmin = 1 (Prompt for credentials on secure desktop)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorAdmin" -Value 1 -Type DWord -Force
# ConsentPromptBehaviorUser = 0 (Automatically deny elevation requests)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorUser" -Value 0 -Type DWord -Force
# EnableLUA = 1 (Enable User Account Control / Admin Approval Mode)
Set-ItemProperty -Path $SystemPath -Name "EnableLUA" -Value 1 -Type DWord -Force
# PromptOnSecureDesktop = 1 (Switch to secure desktop when prompting)
Set-ItemProperty -Path $SystemPath -Name "PromptOnSecureDesktop" -Value 1 -Type DWord -Force
# LocalAccountTokenFilterPolicy = 0 (Apply UAC restrictions to local accounts on network logons)
Set-ItemProperty -Path $SystemPath -Name "LocalAccountTokenFilterPolicy" -Value 0 -Type DWord -Force
# EnableInstallDetection = 1 (Detect application installations and prompt for elevation)
Set-ItemProperty -Path $SystemPath -Name "EnableInstallDetection" -Value 1 -Type DWord -Force
# EnableVirtualization = 1 (Virtualize file and registry write failures to per-user locations)
Set-ItemProperty -Path $SystemPath -Name "EnableVirtualization" -Value 1 -Type DWord -Force

# Configure Windows Sudo command behavior (Enabled = 1 [Force new elevated window])
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (-not (Test-Path $SudoPath)) {
    New-Item -Path $SudoPath -Force | Out-Null
}
Set-ItemProperty -Path $SudoPath -Name "Enabled" -Value 1 -Type DWord -Force

Write-Host "[+] UAC registry values configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit UAC configurations:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-UACPolicies.ps1">Download Script: Test-UACPolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-UACPolicies.ps1
# Verifies local system registry settings for User Account Control.

Write-Host "--- Auditing User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$script:Vulnerable = $false

function Test-UACRegistryValue ($name, $expected, $message) {
    $val = Get-ItemProperty -Path $SystemPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { $null }
    $color = "Red"
    if ($actual -eq $expected) {
        $color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expected') | $message" -ForegroundColor $color
}

Test-UACRegistryValue "ConsentPromptBehaviorAdmin" 1 "Behavior of elevation prompt for administrators"
Test-UACRegistryValue "ConsentPromptBehaviorUser" 0 "Behavior of elevation prompt for standard users"
Test-UACRegistryValue "EnableLUA" 1 "Run all administrators in Admin Approval Mode"
Test-UACRegistryValue "PromptOnSecureDesktop" 1 "Switch to secure desktop when prompting"
Test-UACRegistryValue "LocalAccountTokenFilterPolicy" 0 "UAC network restrictions"
Test-UACRegistryValue "EnableInstallDetection" 1 "Installer detection"
Test-UACRegistryValue "EnableVirtualization" 1 "UAC virtualization"

# Audit Sudo command
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (Test-Path $SudoPath) {
    $SudoState = Get-ItemProperty -Path $SudoPath -Name "Enabled" -ErrorAction SilentlyContinue
    $SudoVal = if ($SudoState) { $SudoState.Enabled } else { 0 }
    $SudoColor = if ($SudoVal -eq 0 -or $SudoVal -eq 1) { "Green" } else { "Red" }
    Write-Host "    - Sudo Command Enabled state: $SudoVal (Required = 1 [New Window] or 0 [Disabled])" -ForegroundColor $SudoColor
    if ($SudoVal -ne 0 -and $SudoVal -ne 1) {
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - Sudo Command Enabled state: Not Configured (Default/Compliant as it inherits disabled)" -ForegroundColor Green
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-UACPolicies.ps1
# Enforces hardened User Account Control (UAC) registry configuration values including network restrictions, installer detection, and virtualization.

Write-Host "--- Hardening User Account Control Policies ---" -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

if (-not (Test-Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

# ConsentPromptBehaviorAdmin = 1 (Prompt for credentials on secure desktop)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorAdmin" -Value 1 -Type DWord -Force
# ConsentPromptBehaviorUser = 0 (Automatically deny elevation requests)
Set-ItemProperty -Path $SystemPath -Name "ConsentPromptBehaviorUser" -Value 0 -Type DWord -Force
# EnableLUA = 1 (Enable User Account Control / Admin Approval Mode)
Set-ItemProperty -Path $SystemPath -Name "EnableLUA" -Value 1 -Type DWord -Force
# PromptOnSecureDesktop = 1 (Switch to secure desktop when prompting)
Set-ItemProperty -Path $SystemPath -Name "PromptOnSecureDesktop" -Value 1 -Type DWord -Force
# LocalAccountTokenFilterPolicy = 0 (Apply UAC restrictions to local accounts on network logons)
Set-ItemProperty -Path $SystemPath -Name "LocalAccountTokenFilterPolicy" -Value 0 -Type DWord -Force
# EnableInstallDetection = 1 (Detect application installations and prompt for elevation)
Set-ItemProperty -Path $SystemPath -Name "EnableInstallDetection" -Value 1 -Type DWord -Force
# EnableVirtualization = 1 (Virtualize file and registry write failures to per-user locations)
Set-ItemProperty -Path $SystemPath -Name "EnableVirtualization" -Value 1 -Type DWord -Force

# Configure Windows Sudo command behavior (Enabled = 1 [Force new elevated window])
$SudoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sudo"
if (-not (Test-Path $SudoPath)) {
    New-Item -Path $SudoPath -Force | Out-Null
}
Set-ItemProperty -Path $SudoPath -Name "Enabled" -Value 1 -Type DWord -Force

Write-Host "[+] UAC registry values configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8002" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-003" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-003] Disable AutoPlay and AutoRun</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/disable-autoplay-autorun.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The AutoPlay and AutoRun features in Windows are designed to automatically execute programs or open media when a removable drive, network share, or CD-ROM is inserted or connected.</xhtml:p>
        <xhtml:p>Attackers exploit these features by placing malicious scripts, payloads, or executables on USB drives or external storage media. If AutoPlay is enabled, connecting the drive triggers automatic execution of these scripts or programs without user interaction or approval, allowing malware to achieve immediate execution in the context of the logged-on user. Disabling AutoPlay across all drive types completely mitigates this physical transmission vector.</xhtml:p>
        <xhtml:p>Additionally, non-volume devices (such as mobile phones, cameras, or media players) can still trigger AutoPlay behavior. Disallowing AutoPlay for non-volume devices ensures these devices do not introduce unauthorized execution pathways when plugged into standard client machines.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\AutoPlay Policies</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn off AutoPlay</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Options</xhtml:em>*: <xhtml:code>All drives</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Set the default behavior for AutoRun</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Options</xhtml:em>*: <xhtml:code>Do not execute any autorun commands</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Disallow Autoplay for non-volume devices</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure Explorer registry keys to disable AutoPlay, AutoRun, and AutoPlay for non-volume devices.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-AutoPlay.ps1">Download Script: Disable-AutoPlay.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-AutoPlay.ps1
# Disables AutoPlay/AutoRun registry settings globally on all drive types and non-volume devices.

Write-Host "--- Disabling AutoPlay and AutoRun ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"

if (-not (Test-Path $ExplorerPath)) {
    New-Item -Path $ExplorerPath -Force | Out-Null
}

# NoDriveTypeAutoRun = 0xFF (255 in decimal) disables AutoRun on all types of drives
Set-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord -Force

# NoAutorun = 1 disables AutoRun commands in inf files
Set-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -Value 1 -Type DWord -Force

# Disallow Autoplay for non-volume devices (NoAutoplayfornonVolume = 1)
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
if (-not (Test-Path $PolExplorerPath)) {
    New-Item -Path $PolExplorerPath -Force | Out-Null
}
Set-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -Value 1 -Type DWord -Force

Write-Host "[+] AutoPlay and AutoRun registry parameters set." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit AutoPlay configurations:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-AutoPlay.ps1">Download Script: Test-AutoPlay.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-AutoPlay.ps1
# Audits local system registry parameters for AutoPlay status.

Write-Host "--- Auditing AutoPlay Configuration ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"

$NoDriveAuto = Get-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -ErrorAction SilentlyContinue
$NoAutoCmd = Get-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -ErrorAction SilentlyContinue
$NoNonVol = Get-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -ErrorAction SilentlyContinue

$NoDriveVal = if ($NoDriveAuto) { $NoDriveAuto.NoDriveTypeAutoRun } else { 0 }
$NoAutoVal = if ($NoAutoCmd) { $NoAutoCmd.NoAutorun } else { 0 }
$NoNonVolVal = if ($NoNonVol) { $NoNonVol.NoAutoplayfornonVolume } else { 0 }

$NoDriveColor = if ($NoDriveVal -eq 255) { "Green" } else { "Red" }
$NoAutoColor = if ($NoAutoVal -eq 1) { "Green" } else { "Red" }
$NoNonVolColor = if ($NoNonVolVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - NoDriveTypeAutoRun: $NoDriveVal (Required = 255 to disable all drives)" -ForegroundColor $NoDriveColor
Write-Host "    - NoAutorun: $NoAutoVal (Required = 1)" -ForegroundColor $NoAutoColor
Write-Host "    - NoAutoplayfornonVolume: $NoNonVolVal (Required = 1)" -ForegroundColor $NoNonVolColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-AutoPlay.ps1
# Disables AutoPlay/AutoRun registry settings globally on all drive types and non-volume devices.

Write-Host "--- Disabling AutoPlay and AutoRun ---" -ForegroundColor Cyan

$ExplorerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"

if (-not (Test-Path $ExplorerPath)) {
    New-Item -Path $ExplorerPath -Force | Out-Null
}

# NoDriveTypeAutoRun = 0xFF (255 in decimal) disables AutoRun on all types of drives
Set-ItemProperty -Path $ExplorerPath -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord -Force

# NoAutorun = 1 disables AutoRun commands in inf files
Set-ItemProperty -Path $ExplorerPath -Name "NoAutorun" -Value 1 -Type DWord -Force

# Disallow Autoplay for non-volume devices (NoAutoplayfornonVolume = 1)
$PolExplorerPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
if (-not (Test-Path $PolExplorerPath)) {
    New-Item -Path $PolExplorerPath -Force | Out-Null
}
Set-ItemProperty -Path $PolExplorerPath -Name "NoAutoplayfornonVolume" -Value 1 -Type DWord -Force

Write-Host "[+] AutoPlay and AutoRun registry parameters set." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8003" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-004" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-004] Block Removable Storage</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/block-removable-storage.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Removable storage media, such as USB flash drives, external SSDs, and optical discs, represent a significant risk vector for corporate network environments.</xhtml:p>
        <xhtml:p>Attackers use USB drives to bypass network-based security boundaries (such as firewalls and intrusion detection systems), introducing malware directly onto local workstation hosts via physical sneakernets. USB drives are also a primary tool for insider threat data exfiltration, enabling users to copy proprietary or sensitive information off company terminals onto untracked hardware. Restricting removable storage access at the operating system level prevents both unauthorized data ingress (malware infection) and data egress (unauthorized data copying).</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Removable Storage Access</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>All Removable Storage classes: Deny all access</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:p>
          <xhtml:em>Alternatively, if you only want to block write access while allowing read-only access (for specific profiles), configure:</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Removable Disks: Deny write access</xhtml:code> -&gt; <xhtml:code>Enabled</xhtml:code>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure registry keys to block all removable storage devices.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Block-RemovableStorage.ps1">Download Script: Block-RemovableStorage.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Block-RemovableStorage.ps1
# Configures local registry parameters to deny access to all removable storage classes.

Write-Host "--- Restricting Removable Storage Devices ---" -ForegroundColor Cyan

$RemovableStoragePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices"

if (-not (Test-Path $RemovableStoragePath)) {
    New-Item -Path $RemovableStoragePath -Force | Out-Null
}

# Deny_All = 1 blocks all removable storage classes
Set-ItemProperty -Path $RemovableStoragePath -Name "Deny_All" -Value 1 -Type DWord

Write-Host "[+] Removable storage block configured." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit removable storage block configurations:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-RemovableStorage.ps1">Download Script: Test-RemovableStorage.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-RemovableStorage.ps1
# Audits registry values for removable storage blocks.

Write-Host "--- Auditing Removable Storage Restrictions ---" -ForegroundColor Cyan

$RemovableStoragePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices"

$DenyAllProp = Get-ItemProperty -Path $RemovableStoragePath -Name "Deny_All" -ErrorAction SilentlyContinue
$DenyAllVal = if ($DenyAllProp) { $DenyAllProp.Deny_All } else { 0 }
$DenyColor = if ($DenyAllVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - Removable Storage Deny_All: $DenyAllVal (Required = 1)" -ForegroundColor $DenyColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Block-RemovableStorage.ps1
# Configures local registry parameters to deny access to all removable storage classes.

Write-Host "--- Restricting Removable Storage Devices ---" -ForegroundColor Cyan

$RemovableStoragePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices"

if (-not (Test-Path $RemovableStoragePath)) {
    New-Item -Path $RemovableStoragePath -Force | Out-Null
}

# Deny_All = 1 blocks all removable storage classes
Set-ItemProperty -Path $RemovableStoragePath -Name "Deny_All" -Value 1 -Type DWord

Write-Host "[+] Removable storage block configured." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8004" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-005" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-005] Restrict Remote Desktop Access</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/restrict-rdp-access.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Remote Desktop Protocol (RDP) is one of the primary mechanisms used by attackers for lateral movement and administrative session hijacking. If inbound RDP is enabled globally on workstations: 1. <xhtml:strong>Lateral Movement</xhtml:strong>: An attacker who compromises a single standard user's credentials with administrative permissions on other machines can RDP from workstation to workstation across the network. 2. <xhtml:strong>Session Hijacking</xhtml:strong>: Attackers can hijack existing administrative RDP sessions using built-in command-line tools (such as <xhtml:code>tscon.exe</xhtml:code>) if they obtain administrator privileges on the system. 3. <xhtml:strong>Password Spraying</xhtml:strong>: Open RDP ports allow attackers to attempt password spraying or brute-force attacks against local administrative accounts.</xhtml:p>
        <xhtml:p>Furthermore, Windows <xhtml:strong>Remote Assistance</xhtml:strong> allows helper connections that can lead to remote code execution or unauthorized access if not properly restricted. Disabling Solicited Remote Assistance and removing any legacy configuration values limits the workstation's attack surface.</xhtml:p>
        <xhtml:p>The safest configuration is to disable Remote Desktop Services and Remote Assistance entirely on all Tier 2 workstations. If RDP is strictly necessary for remote technical support, it must require Network Level Authentication (NLA) and the listening firewall rules must restrict access to authorized management subnets only.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Disable Inbound Remote Desktop Connections (Default Hardening)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Connections</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Allow users to connect remotely by using Remote Desktop Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Enforce NLA and High Encryption (If RDP is Required for Admins)</xhtml:h4>
        <xhtml:p>If RDP is strictly required, enable it but restrict it using the following settings: 1. Under the same path: <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow users to connect remotely by using Remote Desktop Services` -&gt; `Enabled` 2. Navigate to: `Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Security` 3. Configure the following settings: </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Require user authentication for remote connections by using Network Level Authentication</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Setting</xhtml:em>
          <xhtml:em>: `Enabled` </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Set client connection encryption level</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Setting</xhtml:em>
          <xhtml:em>: `Enabled` (Select `High Level` in the options dropdown) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Require use of specific security layer for remote (RDP) connections</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled: SSL</xhtml:code> 4. Deploy local firewall rules via GPO to restrict TCP port 3389 inbound to administrative subnet ranges only.</xhtml:p>
        <xhtml:h4>3. Configure Temporary Folders Deletion on Exit</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Temporary Folders</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Do not delete temp folders upon exit</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code> (ensures session temporary directories are deleted when users log off)</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>4. Disable Solicited Remote Assistance</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Remote Assistance</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure Solicited Remote Assistance</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to disable Remote Desktop and Remote Assistance, and enforce NLA and secure registry keys.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-RemoteDesktop.ps1">Download Script: Disable-RemoteDesktop.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-RemoteDesktop.ps1
# Disables Remote Desktop and Solicited Remote Assistance connections, sets NLA requirements, sets Security Layer to SSL, configures temp folder deletion, and cleans parameters.

Write-Host "--- Restricting Remote Desktop and Remote Assistance Access ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"

# 1. Disable RDP Connections (fDenyTSConnections = 1)
Set-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -Value 1 -Type DWord -Force
Write-Host "[+] Inbound Remote Desktop connections disabled." -ForegroundColor Green

# 2. Enforce Network Level Authentication (UserAuthentication = 1)
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
if (Test-Path $RdpSecPath) {
    Set-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -Value 1 -Type DWord -Force
    Write-Host "[+] Network Level Authentication (NLA) enforced." -ForegroundColor Green
}

# 3. Disable Remote Assistance (fAllowToGetHelp = 0)
Set-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force

# 4. Disable and clean Solicited Remote Assistance Policies, set SSL, and delete temp folders
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $TSPoliciesPath)) {
    New-Item -Path $TSPoliciesPath -Force | Out-Null
}
Set-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -Value 1 -Type DWord -Force

$ParamsToDelete = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
foreach ($Param in $ParamsToDelete) {
    if (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue) {
        Remove-ItemProperty -Path $TSPoliciesPath -Name $Param -Force -ErrorAction SilentlyContinue
    }
}
Write-Host "[+] Remote Desktop policies (SSL, Temp folders, Solicited Help) configured and cleaned." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit Remote Desktop and Remote Assistance status:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-RemoteDesktopStatus.ps1">Download Script: Test-RemoteDesktopStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-RemoteDesktopStatus.ps1
# Audits local RDP, Remote Assistance, security layer, temp folders, and NLA registry configuration and listening firewall ports.

Write-Host "--- Auditing Remote Desktop Configuration ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"

$DenyTS = Get-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -ErrorAction SilentlyContinue
$DenyVal = if ($DenyTS) { $DenyTS.fDenyTSConnections } else { 1 }

$NlaProp = Get-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -ErrorAction SilentlyContinue
$NlaVal = if ($NlaProp) { $NlaProp.UserAuthentication } else { 0 }

$DenyColor = if ($DenyVal -eq 1) { "Green" } else { "Yellow" }
$NlaColor = if ($NlaVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - fDenyTSConnections: $DenyVal (Recommended = 1 to block all)" -ForegroundColor $DenyColor
Write-Host "    - UserAuthentication (NLA): $NlaVal (Required = 1 if RDP is enabled)" -ForegroundColor $NlaColor

# Check if port 3389 firewall rule is active and enabled
$RdpFirewall = Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -ErrorAction SilentlyContinue
if ($RdpFirewall) {
    $FirewallColor = if ($RdpFirewall.Enabled -eq $true) { "Yellow" } else { "Green" }
    Write-Host "    - RDP Inbound Firewall Rule Active: $($RdpFirewall.Enabled)" -ForegroundColor $FirewallColor
}

# Audit Remote Assistance
$GetHelpTS = Get-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -ErrorAction SilentlyContinue
$GetHelpTSVal = if ($GetHelpTS) { $GetHelpTS.fAllowToGetHelp } else { 0 }
$HelpColor = if ($GetHelpTSVal -eq 0) { "Green" } else { "Red" }
Write-Host "    - fAllowToGetHelp (Terminal Server): $GetHelpTSVal (Recommended = 0)" -ForegroundColor $HelpColor

# Audit Solicited Remote Assistance Policy, Security Layer, and Temp Folders
if (Test-Path $TSPoliciesPath) {
    $PolGetHelp = Get-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -ErrorAction SilentlyContinue
    $PolGetHelpVal = if ($PolGetHelp) { $PolGetHelp.fAllowToGetHelp } else { $null }
    
    $PolHelpColor = if ($PolGetHelpVal -eq 0) { "Green" } else { "Red" }
    Write-Host "    - fAllowToGetHelp (Policies): $PolGetHelpVal (Recommended = 0)" -ForegroundColor $PolHelpColor
    
    $SecurityLayerProp = Get-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -ErrorAction SilentlyContinue
    $SecurityLayerVal = if ($SecurityLayerProp) { $SecurityLayerProp.SecurityLayer } else { $null }
    $SecLayerColor = if ($SecurityLayerVal -eq 2) { "Green" } else { "Red" }
    Write-Host "    - SecurityLayer (SSL): $SecurityLayerVal (Required = 2)" -ForegroundColor $SecLayerColor

    $DeleteTempProp = Get-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -ErrorAction SilentlyContinue
    $DeleteTempVal = if ($DeleteTempProp) { $DeleteTempProp.DeleteTempDirsOnExit } else { $null }
    $DeleteTempColor = if ($DeleteTempVal -eq 1) { "Green" } else { "Red" }
    Write-Host "    - DeleteTempDirsOnExit (Temp Folders): $DeleteTempVal (Required = 1)" -ForegroundColor $DeleteTempColor

    $Params = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
    foreach ($Param in $Params) {
        $Val = (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue).$Param
        if ($null -ne $Val) {
            Write-Host "    - VULNERABLE: Solicited Remote Assistance parameter '$Param' is set to '$Val' (Expected: Deleted/Not Configured)" -ForegroundColor Red
        } else {
            Write-Host "    - Parameter '$Param': Not Configured (Correct)" -ForegroundColor Green
        }
    }
} else {
    Write-Host "    - Solicited Remote Assistance Policy Path does not exist" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-RemoteDesktop.ps1
# Disables Remote Desktop and Solicited Remote Assistance connections, sets NLA requirements, sets Security Layer to SSL, configures temp folder deletion, and cleans parameters.

Write-Host "--- Restricting Remote Desktop and Remote Assistance Access ---" -ForegroundColor Cyan

$RdpPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"

# 1. Disable RDP Connections (fDenyTSConnections = 1)
Set-ItemProperty -Path $RdpPath -Name "fDenyTSConnections" -Value 1 -Type DWord -Force
Write-Host "[+] Inbound Remote Desktop connections disabled." -ForegroundColor Green

# 2. Enforce Network Level Authentication (UserAuthentication = 1)
$RdpSecPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
if (Test-Path $RdpSecPath) {
    Set-ItemProperty -Path $RdpSecPath -Name "UserAuthentication" -Value 1 -Type DWord -Force
    Write-Host "[+] Network Level Authentication (NLA) enforced." -ForegroundColor Green
}

# 3. Disable Remote Assistance (fAllowToGetHelp = 0)
Set-ItemProperty -Path $RdpPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force

# 4. Disable and clean Solicited Remote Assistance Policies, set SSL, and delete temp folders
$TSPoliciesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
if (-not (Test-Path $TSPoliciesPath)) {
    New-Item -Path $TSPoliciesPath -Force | Out-Null
}
Set-ItemProperty -Path $TSPoliciesPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "SecurityLayer" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $TSPoliciesPath -Name "DeleteTempDirsOnExit" -Value 1 -Type DWord -Force

$ParamsToDelete = @("MaxTicketExpiryUnits", "MaxTicketExpiry", "fUseMailto", "fAllowFullControl")
foreach ($Param in $ParamsToDelete) {
    if (Get-ItemProperty -Path $TSPoliciesPath -Name $Param -ErrorAction SilentlyContinue) {
        Remove-ItemProperty -Path $TSPoliciesPath -Name $Param -Force -ErrorAction SilentlyContinue
    }
}
Write-Host "[+] Remote Desktop policies (SSL, Temp folders, Solicited Help) configured and cleaned." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8005" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-006" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-006] Restrict Local Administrators Group</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/restrict-local-admins.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Local administrator rights on workstations are a significant source of operational vulnerability. If standard end-users run as local administrators: 1. <xhtml:strong>Malware Propagation</xhtml:strong>: Malware executed by the user runs in an administrative context, allowing it to bypass local firewalls, alter registry hives, disable security controls (like Windows Defender), and persist across reboots. 2. <xhtml:strong>Credential Harvesting</xhtml:strong>: Compromised local admin accounts allow attackers to execute memory-dumping tools (e.g., Mimikatz) to harvest stored domain credentials of other users who have logged on to that machine. 3. <xhtml:strong>Software Control Bypass</xhtml:strong>: Users can install arbitrary, unapproved software, introducing license compliance risks and unmonitored security vulnerabilities.</xhtml:p>
        <xhtml:p>Securing the local Administrators group ensures only local security accounts (like the local <xhtml:code>Administrator</xhtml:code> managed by LAPS) or dedicated workstation support accounts are members. The default <xhtml:code>Domain Users</xhtml:code> or standard domain accounts must never be allowed local administrative rights.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Enforce local Administrators group membership and restrict remote execution via local accounts (UAC remote restrictions): 1. Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>). 2. Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>). 3. <xhtml:strong>Configure Restricted Groups</xhtml:strong>: <xhtml:em> Navigate to: `Computer Configuration\Policies\Windows Settings\Security Settings\Restricted Groups` </xhtml:em> Right-click <xhtml:strong>Restricted Groups</xhtml:strong> and select <xhtml:strong>Add Group</xhtml:strong>. <xhtml:em> Type `Administrators` (or click Browse to find the local group). </xhtml:em> Under <xhtml:strong>Members of this group</xhtml:strong>, define the allowed members: <xhtml:em> `Administrator` (the built-in local administrator account) </xhtml:em>
          <xhtml:code>DomainName\Workstation-Support-Admins</xhtml:code> (dedicated Tier 2 support team group, if used) <xhtml:em> </xhtml:em>Leave out <xhtml:code>Domain Users</xhtml:code> or any other general domain accounts.<xhtml:em> </xhtml:em> Applying this GPO will overwrite the membership of the local Administrators group, immediately removing any account not explicitly listed. 4. <xhtml:strong>Configure Local Account Token Filter Policy</xhtml:strong>: <xhtml:em> Navigate to: `Computer Configuration\Preferences\Windows Settings\Registry` </xhtml:em> Right-click <xhtml:strong>Registry</xhtml:strong> and select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>. <xhtml:em> Set </xhtml:em>
          <xhtml:em>Action</xhtml:em>
          <xhtml:em>: `Update` </xhtml:em> Set <xhtml:strong>Hive</xhtml:strong>: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          <xhtml:em> Set </xhtml:em>
          <xhtml:em>Key Path</xhtml:em>
          <xhtml:em>: `SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System` </xhtml:em> Set <xhtml:strong>Value name</xhtml:strong>: <xhtml:code>LocalAccountTokenFilterPolicy</xhtml:code>
          <xhtml:em> Set </xhtml:em>
          <xhtml:em>Value type</xhtml:em>
          <xhtml:em>: `REG_DWORD` </xhtml:em> Set <xhtml:strong>Value data</xhtml:strong>: <xhtml:code>0</xhtml:code>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and remediate unauthorized administrative accounts in the local Administrators group and enforce local account remote token restrictions.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Clean-LocalAdministrators.ps1">Download Script: Clean-LocalAdministrators.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Clean-LocalAdministrators.ps1
# Removes unauthorized domain or local accounts from the local Administrators group and disables local account remote token filtering bypass.

Write-Host "--- Restricting Local Administrators Group ---" -ForegroundColor Cyan

# Define the list of authorized members
# The built-in Administrator account (RID 500) and authorized domain support groups.
$AuthorizedMembers = @("Administrator", "Workstation-Support-Admins")

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    foreach ($Member in $LocalAdmins) {
        # Check if the member is not in the authorized list
        $Match = $false
        foreach ($Auth in $AuthorizedMembers) {
            # Check for exact matches or matches against SAM / SID formats
            if ($Member.Name -eq $Auth -or $Member.Name -like "*\$Auth" -or $Member.Name -eq "$env:COMPUTERNAME\$Auth") {
                $Match = $true
                break
            }
        }
        
        if (-not $Match) {
            Write-Host "[-] Removing unauthorized member: $($Member.Name) (Source: $($Member.PrincipalSource))" -ForegroundColor Yellow
            try {
                Remove-LocalGroupMember -Group "Administrators" -Member $Member.Name -ErrorAction Stop
                Write-Host "    Successfully removed: $($Member.Name)" -ForegroundColor Green
            } catch {
                Write-Error "    Failed to remove: $($Member.Name). Error: $($_.Exception.Message)"
            }
        } else {
            Write-Host "[+] Member authorized: $($Member.Name)" -ForegroundColor Green
        }
    }
} else {
    Write-Error "Could not retrieve members of local Administrators group."
}

# Enforce LocalAccountTokenFilterPolicy = 0
$RegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "LocalAccountTokenFilterPolicy"

try {
    if (-not (Test-Path $RegistryPath)) {
        New-Item -Path $RegistryPath -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryPath -Name $ValueName -Value 0 -Type DWord -Force | Out-Null
    Write-Host "[+] LocalAccountTokenFilterPolicy configured to 0." -ForegroundColor Green
} catch {
    Write-Error "Failed to configure LocalAccountTokenFilterPolicy. Error: $($_.Exception.Message)"
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local Administrators group memberships and UAC token filtering policy:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-LocalAdministrators.ps1">Download Script: Test-LocalAdministrators.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-LocalAdministrators.ps1
# Audits membership of the local Administrators group and checks local account remote token filtering bypass policy.

Write-Host "--- Auditing Local Administrators Group ---" -ForegroundColor Cyan

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    Write-Host "[*] Current members of local Administrators group:" -ForegroundColor Yellow
    foreach ($Member in $LocalAdmins) {
        # Flag any domain user accounts that might have been added to administrators group
        $StatusColor = "Green"
        if ($Member.PrincipalSource -eq "ActiveDirectory" -and $Member.Name -notmatch "Workstation-Support-Admins") {
            $StatusColor = "Red"
            Write-Host "    - VULNERABLE: Domain Account '$($Member.Name)' has local admin rights." -ForegroundColor $StatusColor
        } else {
            Write-Host "    - Member: $($Member.Name) | Source: $($Member.PrincipalSource) | Class: $($Member.ObjectClass)" -ForegroundColor $StatusColor
        }
    }
} else {
    Write-Error "Failed to retrieve local Administrators group members."
}

# Audit LocalAccountTokenFilterPolicy
$RegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "LocalAccountTokenFilterPolicy"

if (Test-Path $RegistryPath) {
    $Val = (Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue).$ValueName
    if ($Val -eq 0) {
        Write-Host "[+] LocalAccountTokenFilterPolicy is configured correctly (0)." -ForegroundColor Green
    } elseif ($null -eq $Val) {
        Write-Host "[-] LocalAccountTokenFilterPolicy is not explicitly set (Expected: 0)." -ForegroundColor Red
    } else {
        Write-Host "[-] LocalAccountTokenFilterPolicy is vulnerable: $Val (Expected: 0)." -ForegroundColor Red
    }
} else {
    Write-Host "[-] LocalAccountTokenFilterPolicy is not configured (Expected: 0)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Clean-LocalAdministrators.ps1
# Removes unauthorized domain or local accounts from the local Administrators group and disables local account remote token filtering bypass.

Write-Host "--- Restricting Local Administrators Group ---" -ForegroundColor Cyan

# Define the list of authorized members
# The built-in Administrator account (RID 500) and authorized domain support groups.
$AuthorizedMembers = @("Administrator", "Workstation-Support-Admins")

$LocalAdmins = Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue

if ($LocalAdmins) {
    foreach ($Member in $LocalAdmins) {
        # Check if the member is not in the authorized list
        $Match = $false
        foreach ($Auth in $AuthorizedMembers) {
            # Check for exact matches or matches against SAM / SID formats
            if ($Member.Name -eq $Auth -or $Member.Name -like "*\$Auth" -or $Member.Name -eq "$env:COMPUTERNAME\$Auth") {
                $Match = $true
                break
            }
        }
        
        if (-not $Match) {
            Write-Host "[-] Removing unauthorized member: $($Member.Name) (Source: $($Member.PrincipalSource))" -ForegroundColor Yellow
            try {
                Remove-LocalGroupMember -Group "Administrators" -Member $Member.Name -ErrorAction Stop
                Write-Host "    Successfully removed: $($Member.Name)" -ForegroundColor Green
            } catch {
                Write-Error "    Failed to remove: $($Member.Name). Error: $($_.Exception.Message)"
            }
        } else {
            Write-Host "[+] Member authorized: $($Member.Name)" -ForegroundColor Green
        }
    }
} else {
    Write-Error "Could not retrieve members of local Administrators group."
}

# Enforce LocalAccountTokenFilterPolicy = 0
$RegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "LocalAccountTokenFilterPolicy"

try {
    if (-not (Test-Path $RegistryPath)) {
        New-Item -Path $RegistryPath -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryPath -Name $ValueName -Value 0 -Type DWord -Force | Out-Null
    Write-Host "[+] LocalAccountTokenFilterPolicy configured to 0." -ForegroundColor Green
} catch {
    Write-Error "Failed to configure LocalAccountTokenFilterPolicy. Error: $($_.Exception.Message)"
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8006" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-008" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-008] WSUS Client Configuration</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/wsus-client-config.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In an isolated, air-gapped network, workstations cannot connect directly to Microsoft's online Update servers. If the system is left in its default configuration: 1. <xhtml:strong>DNS/Firewall Pollution</xhtml:strong>: Workstations will continuously attempt to resolve and connect to public Windows Update URLs (e.g., <xhtml:code>*.update.microsoft.com</xhtml:code>), filling firewall and local DNS resolver cache logs with timeouts and block events. 2. <xhtml:strong>Missing Updates</xhtml:strong>: Workstations will fail to receive security patches, critical updates, and Windows Defender definitions. 3. <xhtml:strong>Control Bypass</xhtml:strong>: Attackers or unapproved software could attempt to install out-of-band features or packages if update routes are not explicitly locked to internal sources.</xhtml:p>
        <xhtml:p>Enforcing the intranet update service location redirects all system update queries to the local WSUS server. Furthermore, enforcing Windows <xhtml:strong>Delivery Optimization</xhtml:strong> download mode to <xhtml:code>Group (2)</xhtml:code> limits peer-to-peer update sharing strictly to computers within the same active directory domain/group or local subnet boundaries, reducing bandwidth constraints on WAN/intranet segments and preventing unmanaged peer sharing.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Windows Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configure Automatic Updates</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure automatic updating</xhtml:em>*: <xhtml:code>4 - Auto download and schedule the install</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the service location:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Specify intranet Microsoft update service location</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet update service for detecting updates</xhtml:em>*: <xhtml:code>http://local-wsus.domain.local:8530</xhtml:code> (Replace with your internal WSUS FQDN or IP)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set the intranet statistics server</xhtml:em>*: <xhtml:code>http://local-wsus.domain.local:8530</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Do not connect to any Windows Update Internet locations</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code> (blocks fallback to public servers)</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Delivery Optimization</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Download Mode</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Download Mode</xhtml:em>*: <xhtml:code>Group (2)</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure registry keys to enforce local WSUS parameters and Delivery Optimization download mode.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-WSUSClientConfiguration.ps1">Download Script: Set-WSUSClientConfiguration.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-WSUSClientConfiguration.ps1
# Configures local registry keys to point the Windows Update client to the intranet WSUS server and enforces DO Group mode.

Write-Host "--- Configuring WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

# 1. Create keys if they do not exist
if (-not (Test-Path $WUPath)) {
    New-Item -Path $WUPath -Force | Out-Null
}
if (-not (Test-Path $WUAUPath)) {
    New-Item -Path $WUAUPath -Force | Out-Null
}
if (-not (Test-Path $DOPath)) {
    New-Item -Path $DOPath -Force | Out-Null
}

# Define intranet WSUS URL
$WSUSServer = "http://local-wsus.domain.local:8530"

# 2. Configure update location and statistics server
Set-ItemProperty -Path $WUPath -Name "WUServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "WUStatusServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "DoNotConnectToWindowsUpdateInternetLocations" -Value 1 -Type DWord -Force

# 3. Configure Automatic Updates behavior (AUOptions = 4: Auto Download &amp; Schedule)
Set-ItemProperty -Path $WUAUPath -Name "NoAutoUpdate" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "AUOptions" -Value 4 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "UseWUServer" -Value 1 -Type DWord -Force

# 4. Enforce DODownloadMode = 2 (Group)
Set-ItemProperty -Path $DOPath -Name "DODownloadMode" -Value 2 -Type DWord -Force

Write-Host "[+] Local WSUS parameters and Delivery Optimization download mode applied." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the WSUS client configuration status:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-WSUSClientStatus.ps1">Download Script: Test-WSUSClientStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-WSUSClientStatus.ps1
# Audits registry values to verify WSUS server assignment and Delivery Optimization configuration.

Write-Host "--- Auditing WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

$WUServerProp = Get-ItemProperty -Path $WUPath -Name "WUServer" -ErrorAction SilentlyContinue
$WUStatusProp = Get-ItemProperty -Path $WUPath -Name "WUStatusServer" -ErrorAction SilentlyContinue
$UseWUServerProp = Get-ItemProperty -Path $WUAUPath -Name "UseWUServer" -ErrorAction SilentlyContinue

$WUServerVal = if ($WUServerProp) { $WUServerProp.WUServer } else { "" }
$WUStatusVal = if ($WUStatusProp) { $WUStatusProp.WUStatusServer } else { "" }
$UseWUVal = if ($UseWUServerProp) { $UseWUServerProp.UseWUServer } else { 0 }

$ServerColor = if ($WUServerVal -like "http*") { "Green" } else { "Red" }
$UseColor = if ($UseWUVal -eq 1) { "Green" } else { "Red" }

Write-Host "    - Intranet WUServer: $WUServerVal" -ForegroundColor $ServerColor
Write-Host "    - Intranet WUStatusServer: $WUStatusVal" -ForegroundColor $ServerColor
Write-Host "    - UseWUServer Active: $UseWUVal (Required = 1)" -ForegroundColor $UseColor

# Audit Delivery Optimization
$DOVal = if (Test-Path $DOPath) { (Get-ItemProperty -Path $DOPath -Name "DODownloadMode" -ErrorAction SilentlyContinue).DODownloadMode } else { $null }
$DOColor = if ($DOVal -eq 2) { "Green" } else { "Red" }
Write-Host "    - Delivery Optimization DODownloadMode: $($DOVal | Out-String).Trim() (Expected = 2)" -ForegroundColor $DOColor</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-WSUSClientConfiguration.ps1
# Configures local registry keys to point the Windows Update client to the intranet WSUS server and enforces DO Group mode.

Write-Host "--- Configuring WSUS Client Settings ---" -ForegroundColor Cyan

$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$WUAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$DOPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"

# 1. Create keys if they do not exist
if (-not (Test-Path $WUPath)) {
    New-Item -Path $WUPath -Force | Out-Null
}
if (-not (Test-Path $WUAUPath)) {
    New-Item -Path $WUAUPath -Force | Out-Null
}
if (-not (Test-Path $DOPath)) {
    New-Item -Path $DOPath -Force | Out-Null
}

# Define intranet WSUS URL
$WSUSServer = "http://local-wsus.domain.local:8530"

# 2. Configure update location and statistics server
Set-ItemProperty -Path $WUPath -Name "WUServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "WUStatusServer" -Value $WSUSServer -Type String -Force
Set-ItemProperty -Path $WUPath -Name "DoNotConnectToWindowsUpdateInternetLocations" -Value 1 -Type DWord -Force

# 3. Configure Automatic Updates behavior (AUOptions = 4: Auto Download &amp; Schedule)
Set-ItemProperty -Path $WUAUPath -Name "NoAutoUpdate" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "AUOptions" -Value 4 -Type DWord -Force
Set-ItemProperty -Path $WUAUPath -Name "UseWUServer" -Value 1 -Type DWord -Force

# 4. Enforce DODownloadMode = 2 (Group)
Set-ItemProperty -Path $DOPath -Name "DODownloadMode" -Value 2 -Type DWord -Force

Write-Host "[+] Local WSUS parameters and Delivery Optimization download mode applied." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8008" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-009" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-009] Enable UEFI Secure Boot</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-secure-boot.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Secure Boot is a security standard developed by members of the PC industry to help ensure that a device boots using only software that is trusted by the Original Equipment Manufacturer (OEM).</xhtml:p>
        <xhtml:p>When the PC starts, the firmware checks the signature of each piece of boot software, including UEFI firmware drivers (also known as Option ROMs), EFI applications, and the operating system. If the signatures are valid, the PC boots, and the firmware gives control to the operating system.</xhtml:p>
        <xhtml:p>If Secure Boot is disabled: 1. <xhtml:strong>Bootkits &amp; Rootkits</xhtml:strong>: Attackers with physical access or local administrator privileges can replace the system bootloader with a malicious bootloader (bootkit). This bootkit executes before the Windows operating system loads, allowing it to bypass all Windows security controls, disable antivirus software, and run completely undetected. 2. <xhtml:strong>Virtualization-Based Security</xhtml:strong>: Advanced Windows defenses (like Credential Guard and Device Guard) depend on hardware-rooted trust. If Secure Boot is disabled, Virtualization-Based Security (VBS) cannot verify platform integrity, rendering these protections ineffective.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual UEFI Firmware Configuration (Preferred)</xhtml:h3>
        <xhtml:p>UEFI Secure Boot must be enabled in the hardware firmware menu directly (BIOS settings) during system startup:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Turn on or restart the workstation and access the UEFI utility screen by pressing the vendor-specific key during POST (typically Delete, F2, F10, or F12).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Secure Boot</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure </xhtml:em>
            <xhtml:em>Secure Boot</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure the </xhtml:em>
            <xhtml:em>Secure Boot Mode</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Deployed</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>User Mode</xhtml:em>* (not Setup Mode).</xhtml:li>
          <xhtml:li>Save the configuration and restart the workstation.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Since Secure Boot is a hardware firmware configuration, it cannot be turned on from within Windows using registry settings. However, you can programmatically audit the state of Secure Boot to flag non-compliant hardware.</xhtml:p>
        <xhtml:p>Run the following script to check the status of Secure Boot on the local machine:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-SecureBoot.ps1">Download Script: Audit-SecureBoot.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-SecureBoot.ps1
# Description: Queries UEFI Secure Boot parameters and audits UEFI Secure Boot status.

Write-Host "--- Auditing UEFI Secure Boot ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Verify boot environment type
if ($env:firmware_type -eq "UEFI") {
    Write-Host "    - Boot Environment Type: UEFI" -ForegroundColor Green
} else {
    Write-Host "    - VULNERABLE: System booted in Legacy BIOS mode (CSM enabled) or firmware type is unrecognized." -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Verify Secure Boot status
try {
    # Confirm-SecureBootUEFI returns $true if Secure Boot is active, $false if disabled,
    # and throws an exception if the platform does not support UEFI or Secure Boot.
    $SecureBootState = Confirm-SecureBootUEFI -ErrorAction Stop
    
    $Color = if ($SecureBootState -eq $true) { "Green" } else { "Red" }
    Write-Host "    - Secure Boot Active: $SecureBootState" -ForegroundColor $Color
    if ($SecureBootState -eq $false) { $script:NonCompliant = $true }
} catch [System.PlatformNotSupportedException] {
    Write-Host "    - VULNERABLE: UEFI Secure Boot is not supported on this platform (Legacy BIOS mode)." -ForegroundColor Red
    $script:NonCompliant = $true
} catch {
    # If cmdlet throws unauthorized access or not enabled error
    Write-Host "    - VULNERABLE: Secure Boot is disabled in firmware or cannot be verified. Error: $($_.Exception.Message)" -ForegroundColor Red
    $script:NonCompliant = $true
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8009" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-010" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-010] Enable VBS and Credential Guard</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-vbs-credential-guard.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Virtualization-Based Security (VBS) uses hardware virtualization features to create and isolate a secure region of memory from the normal operating system.</xhtml:p>
        <xhtml:p>Windows Defender <xhtml:strong>Credential Guard</xhtml:strong> runs inside this isolated VBS environment (known as the secure kernel). By moving NTLM password hashes, Kerberos Ticket Granting Tickets (TGTs), and other domain credentials into this virtualized container, Credential Guard ensures they are inaccessible to the standard operating system.</xhtml:p>
        <xhtml:p>If VBS and Credential Guard are not enabled: 1. <xhtml:strong>LSASS Access</xhtml:strong>: Attackers running with administrative rights on the workstation can query the LSASS process memory space and extract Active Directory authentication tokens using memory-dumping tools (e.g., Mimikatz). 2. <xhtml:strong>Pass-the-Hash / Pass-the-Ticket</xhtml:strong>: Attackers can use the extracted hashes or Kerberos tickets to log on to other domain systems, leading to rapid lateral movement and domain compromise.</xhtml:p>
        <xhtml:p>Enforcing VBS and Credential Guard prevents in-memory credential harvesting, breaking the primary lateral movement escalation vector.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn On Virtualization Based Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Select Platform Security Level</xhtml:em>*: <xhtml:code>Secure Boot</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Virtualization Based Protection of Code Integrity</xhtml:em>*: <xhtml:code>Enabled with UEFI lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Credential Guard Configuration</xhtml:em>*: <xhtml:code>Enabled with UEFI lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Secure Launch Configuration</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Require UEFI Memory Attributes Table</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:p>
          <xhtml:em>Note: The "Enabled with UEFI lock" setting ensures that an administrator cannot remotely disable Credential Guard via registry changes alone; it requires physical access to the machine to clear UEFI variables on reboot.</xhtml:em>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure registry keys to enable VBS and Credential Guard.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enable-VBSCredentialGuard.ps1">Download Script: Enable-VBSCredentialGuard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enable-VBSCredentialGuard.ps1
# Configures local registry keys to activate VBS and Credential Guard.

Write-Host "--- Enforcing VBS &amp; Credential Guard ---" -ForegroundColor Cyan

$DeviceGuardPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard"

if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

# Enable Virtualization-Based Security (VBS)
Set-ItemProperty -Path $DeviceGuardPath -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
# RequirePlatformSecurityFeatures = 1 (Secure Boot)
Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord
# HypervisorEnforcedCodeIntegrity = 1 (HVCI / Memory Integrity Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "HypervisorEnforcedCodeIntegrity" -Value 1 -Type DWord
# LsaCfgFlags = 1 (Credential Guard Enabled with UEFI Lock)
Set-ItemProperty -Path $DeviceGuardPath -Name "LsaCfgFlags" -Value 1 -Type DWord
# ConfigureSystemGuardLaunch = 1 (Secure Launch Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "ConfigureSystemGuardLaunch" -Value 1 -Type DWord
# HVCIMATRequired = 1 (Require UEFI Memory Attributes Table)
Set-ItemProperty -Path $DeviceGuardPath -Name "HVCIMATRequired" -Value 1 -Type DWord

Write-Host "[+] VBS and Credential Guard registry settings applied. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit VBS and Credential Guard status using WMI:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-VBSCredentialGuard.ps1">Download Script: Test-VBSCredentialGuard.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-VBSCredentialGuard.ps1
# Queries the local Win32_DeviceGuard class to verify active protection states.

Write-Host "--- Auditing Virtualization-Based Security Baseline ---" -ForegroundColor Cyan

try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    
    # SecurityServicesRunning: 1 = Credential Guard, 2 = HVCI
    $CredGuardRunning = $DG.SecurityServicesRunning -contains 1
    $HvciRunning = $DG.SecurityServicesRunning -contains 2
    
    $VbsColor = if ($DG.VirtualizationBasedSecurityStatus -eq 2) { "Green" } else { "Red" }
    $CredColor = if ($CredGuardRunning) { "Green" } else { "Red" }
    $HvciColor = if ($HvciRunning) { "Green" } else { "Red" }
    
    Write-Host "    - VBS Status: $($DG.VirtualizationBasedSecurityStatus) (Required = 2 [Running])" -ForegroundColor $VbsColor
    Write-Host "    - Credential Guard Running: $CredGuardRunning (Required = True)" -ForegroundColor $CredColor
    Write-Host "    - Hypervisor Code Integrity Running: $HvciRunning (Required = True)" -ForegroundColor $HvciColor
    
    # Query registry properties for System Guard and UEFI MAT
    $SystemGuard = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" -Name "ConfigureSystemGuardLaunch" -ErrorAction SilentlyContinue).ConfigureSystemGuardLaunch
    $MatRequired = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" -Name "HVCIMATRequired" -ErrorAction SilentlyContinue).HVCIMATRequired
    
    $SgColor = if ($SystemGuard -eq 1) { "Green" } else { "Red" }
    $MatColor = if ($MatRequired -eq 1) { "Green" } else { "Red" }
    
    Write-Host "    - System Guard Secure Launch: $SystemGuard (Required = 1)" -ForegroundColor $SgColor
    Write-Host "    - UEFI Memory Attributes Table Required: $MatRequired (Required = 1)" -ForegroundColor $MatColor
} catch {
    Write-Host "    - VULNERABLE: DeviceGuard WMI class could not be queried. VBS is likely disabled." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enable-VBSCredentialGuard.ps1
# Configures local registry keys to activate VBS and Credential Guard.

Write-Host "--- Enforcing VBS &amp; Credential Guard ---" -ForegroundColor Cyan

$DeviceGuardPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard"

if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

# Enable Virtualization-Based Security (VBS)
Set-ItemProperty -Path $DeviceGuardPath -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
# RequirePlatformSecurityFeatures = 1 (Secure Boot)
Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord
# HypervisorEnforcedCodeIntegrity = 1 (HVCI / Memory Integrity Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "HypervisorEnforcedCodeIntegrity" -Value 1 -Type DWord
# LsaCfgFlags = 1 (Credential Guard Enabled with UEFI Lock)
Set-ItemProperty -Path $DeviceGuardPath -Name "LsaCfgFlags" -Value 1 -Type DWord
# ConfigureSystemGuardLaunch = 1 (Secure Launch Enabled)
Set-ItemProperty -Path $DeviceGuardPath -Name "ConfigureSystemGuardLaunch" -Value 1 -Type DWord
# HVCIMATRequired = 1 (Require UEFI Memory Attributes Table)
Set-ItemProperty -Path $DeviceGuardPath -Name "HVCIMATRequired" -Value 1 -Type DWord

Write-Host "[+] VBS and Credential Guard registry settings applied. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8010" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-011" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-011] Configure Windows Defender Application Control</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-wdac.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Traditional signature-based antivirus solutions scan for known malware patterns. However, they are easily bypassed by custom, compiled executables, dynamic scripts, or zero-day payloads.</xhtml:p>
        <xhtml:p>
          <xhtml:strong>Windows Defender Application Control (WDAC)</xhtml:strong> is a kernel-enforced application control framework. Instead of asking "Is this file malicious?", WDAC asks "Is this file explicitly trusted?".</xhtml:p>
        <xhtml:p>If WDAC is not configured: 1. <xhtml:strong>Payload Execution</xhtml:strong>: Standard users can execute downloaded scripts (e.g., PowerShell, VBScript) or binary files, facilitating initial access. 2. <xhtml:strong>Antivirus Bypass</xhtml:strong>: Attackers can run obfuscated code, compile payloads on the target endpoint using built-in Windows compilers (e.g., <xhtml:code>csc.exe</xhtml:code>), or run memory injection scripts that standard antivirus signatures miss.</xhtml:p>
        <xhtml:p>Deploying a strict WDAC baseline ensures that only binaries and scripts signed by Microsoft, trusted system developers, or located in protected directories (such as Windows system folders) are allowed to execute.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To deploy WDAC via Group Policy, the policy XML must first be generated, compiled, and placed in a shared intranet network share.</xhtml:p>
        <xhtml:h4>1. Generate and Compile the Policy (on a Reference Machine)</xhtml:h4>
        <xhtml:p>Run the following PowerShell commands to generate the Microsoft Default Windows baseline policy: <xhtml:code />
          <xhtml:code>powershell # Generate the baseline policy XML New-CIPolicy -MultiplePolicyFormat -Level FilePublisher -FilePath "C:\WDAC\BaselinePolicy.xml" -UserPEs  # Compile the XML policy into a binary CIP file ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\BaselinePolicy.xml" -BinaryFilePath "C:\WDAC\BaselinePolicy.cip" </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:h4>2. Deploy the Policy via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Copy the compiled <xhtml:code>BaselinePolicy.cip</xhtml:code> file to a local secure directory on the target clients (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or host it on a network path.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit the GPO linked to your workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the path to the policy file (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code> or a UNC share path).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to generate a baseline WDAC policy, enable Audit Mode, and configure local registry parameters.</xhtml:p>
        <xhtml:h1>Configure-WDACLocalPolicy.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-WDACLocalPolicy.ps1">Download Script: Configure-WDACLocalPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-WDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\DefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the running WDAC policy states:</xhtml:em>
        </xhtml:p>
        <xhtml:h1>Test-WDACStatus.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-WDACStatus.ps1">Download Script: Test-WDACStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-WDACStatus.ps1
# Description: Audits the local system to check if Code Integrity policies and HVCI are active.

Write-Host "--- Auditing WDAC State ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Query WMI class for Code Integrity status
try {
    $CI = Get-CimInstance -Namespace "Root\Microsoft\Windows\CI" -ClassName "MSFT_Sipolicy" -ErrorAction Stop
    if ($null -ne $CI -and $CI.Count -gt 0) {
        Write-Host "`n[+] Found $($CI.Count) active Code Integrity policies." -ForegroundColor Green
        foreach ($Policy in $CI) {
            Write-Host "    - Policy: $($Policy.FriendlyName) | ID: $($Policy.PolicyID) | Enforced: $($Policy.EnforcementMode)" -ForegroundColor Green
        }
    } else {
        Write-Host "`n[-] No active Code Integrity / WDAC policies detected via WMI." -ForegroundColor Yellow
    }
} catch {
    Write-Host "`n[-] Could not query WMI MSFT_Sipolicy. This is expected if no WDAC policies are currently deployed." -ForegroundColor Gray
}

# 2. Check Memory Integrity (HVCI) configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: One or more driver security controls are not configured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: WDAC driver settings and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-WDACLocalPolicy.ps1
# Description: Generates a baseline local Code Integrity policy, sets it to Audit Mode, and compiles it.

Write-Host "--- Configuring WDAC Local Policy Baseline ---" -ForegroundColor Cyan

# Create working directories
$WdacDir = "C:\Windows\System32\CodeIntegrity"
if (-not (Test-Path $WdacDir)) {
    New-Item -Path $WdacDir -ItemType Directory -Force | Out-Null
}

# 1. Generate the Default Windows Policy
Write-Host "[+] Generating Default Windows code integrity rules..." -ForegroundColor Gray
$PolicyXml = "C:\Windows\Temp\DefaultWindows.xml"
$PolicyBin = "$WdacDir\SIPolicy.p7b"

# Create a policy based on Microsoft's default rules (trusts Windows, Store, and Driver files)
New-CIPolicy -FilePath $PolicyXml -Level Windows -UserPEs -ErrorAction Stop

# 2. Set Policy to Audit Mode (Rule Option 3 represents Audit Mode)
Write-Host "[+] Setting WDAC policy to Audit Mode for baseline logging..." -ForegroundColor Gray
Set-RuleOption -FilePath $PolicyXml -Option 3 -ErrorAction SilentlyContinue

# 3. Compile the XML into the binary policy expected by the bootloader
Write-Host "[+] Compiling Code Integrity XML into SIPolicy.p7b..." -ForegroundColor Gray
ConvertFrom-CIPolicy -XmlFilePath $PolicyXml -BinaryFilePath $PolicyBin -ErrorAction Stop

# Cleanup temp files
if (Test-Path $PolicyXml) { Remove-Item $PolicyXml -Force }

Write-Host "[+] Local WDAC baseline policy configured. Reboot required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8011" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-012" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-012] Enable BitLocker and Network Unlock</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-bitlocker.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>BitLocker Drive Encryption protects the operating system volume from offline attacks, data tampering, and data theft when the device is powered off or stolen. Without full disk encryption, an attacker with physical access to a workstation can extract the hard drive, mount it on a non-secure system, bypass operating system security controls, dump local password databases (SAM), and access cached domain credentials.</xhtml:p>
        <xhtml:p>Enforcing specific BitLocker startup parameters, such as a minimum PIN length of at least 6 characters, ensures that if a startup PIN is used, it cannot be easily brute-forced. Restricting how the TPM, startup keys, and PINs are configured ensures consistent security policy application.</xhtml:p>
        <xhtml:p>To maximize security, standard endpoints (Tier 2) should use <xhtml:strong>BitLocker Network Unlock</xhtml:strong> to prevent operational overhead in managing startup PINs for thousands of workstations.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy and Server Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Configure the WDS Server for Network Unlock</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Install the <xhtml:strong>Windows Deployment Services (WDS)</xhtml:strong> role on an internal Windows Server.</xhtml:li>
          <xhtml:li>In Server Manager, select <xhtml:strong>Add Roles and Features</xhtml:strong> and check <xhtml:strong>BitLocker Network Unlock</xhtml:strong> under Features.</xhtml:li>
          <xhtml:li>Open the Local PKI CA console (<xhtml:code>certsrv.msc</xhtml:code>) and issue a certificate using the <xhtml:strong>BitLocker Network Unlock</xhtml:strong> template.</xhtml:li>
          <xhtml:li>Export the certificate public key (<xhtml:code>.cer</xhtml:code> file) and export the private key (<xhtml:code>.pfx</xhtml:code> file).</xhtml:li>
          <xhtml:li>Import the <xhtml:code>.pfx</xhtml:code> private key certificate into the local WDS server's <xhtml:strong>Local Computer\Personal</xhtml:strong> certificate store.</xhtml:li>
          <xhtml:li>Restart the WDS service (<xhtml:code>wdssvc</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Distribute the Network Unlock Certificate via GPO</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit your GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Policies</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>BitLocker Network Unlock</xhtml:strong> and select <xhtml:strong>Add Network Unlock Certificate</xhtml:strong>.</xhtml:li>
          <xhtml:li>Import the public <xhtml:code>.cer</xhtml:code> file exported in Step 1.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Enforce GPO BitLocker Settings</xhtml:h4>
        <xhtml:p>Navigate to <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption</xhtml:code> and configure:</xhtml:p>
        <xhtml:h5>1. General Settings</xhtml:h5>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Allow Network Unlock at startup</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure minimum PIN length for startup</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (Minimum characters: <xhtml:strong>6</xhtml:strong>)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Choose drive encryption method and cipher strength (Windows 10 [Version 1511] and later)</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (OS, Fixed, and Removable: <xhtml:strong>XTS-AES 256-bit</xhtml:strong>)</xhtml:li>
        </xhtml:ul>
        <xhtml:h5>2. Operating System Drives</xhtml:h5>
        <xhtml:p>Navigate to <xhtml:code>Operating System Drives</xhtml:code> subfolder: <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Require additional authentication at startup` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Allow BitLocker without a compatible TPM</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong> (unchecked) <xhtml:em> `Configure TPM startup` -&gt; </xhtml:em>
          <xhtml:em>Require TPM</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Configure TPM startup PIN</xhtml:code> -&gt; <xhtml:strong>Allow startup PIN with TPM</xhtml:strong> (Allows Network Unlock auto-unlock) <xhtml:em> `Configure TPM startup key` -&gt; </xhtml:em>
          <xhtml:em>Allow startup key with TPM</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Configure TPM startup key and PIN</xhtml:code> -&gt; <xhtml:strong>Allow startup key and PIN with TPM</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow enhanced PINs for startup` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Allow Secure Boot for integrity validation</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Choose how BitLocker-protected operating system drives can be recovered` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Allow data recovery agent</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong> (unchecked) <xhtml:em> `Configure user storage of BitLocker recovery information` -&gt; </xhtml:em>
          <xhtml:em>Require 48-digit recovery password</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Configure user storage of BitLocker recovery key</xhtml:code> -&gt; <xhtml:strong>Do not allow 256-bit recovery key</xhtml:strong>
          <xhtml:em> `Omit recovery options from the BitLocker setup wizard` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked) </xhtml:em>
          <xhtml:code>Save BitLocker recovery information to AD DS for operating system drives</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (checked) <xhtml:em> `Configure storage of BitLocker recovery information to AD DS` -&gt; </xhtml:em>
          <xhtml:em>Store recovery passwords and key packages</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Do not enable BitLocker until recovery information is stored to AD DS for operating system drives</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (checked) <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Configure use of hardware-based encryption for operating system drives` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure use of passwords for operating system drives</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
        </xhtml:p>
        <xhtml:h5>3. Fixed Data Drives</xhtml:h5>
        <xhtml:p>Navigate to <xhtml:code>Fixed Data Drives</xhtml:code> subfolder: <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow access to BitLocker-protected fixed data drives from earlier versions of Windows` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Choose how BitLocker-protected fixed drives can be recovered</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> `Allow data recovery agent` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked) </xhtml:em>
          <xhtml:code>Configure user storage of BitLocker recovery information</xhtml:code> -&gt; <xhtml:strong>Allow 48-digit recovery password</xhtml:strong>
          <xhtml:em> `Configure user storage of BitLocker recovery key` -&gt; </xhtml:em>
          <xhtml:em>Allow 256-bit recovery key</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Omit recovery options from the BitLocker setup wizard</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (checked) <xhtml:em> `Save BitLocker recovery information to AD DS for fixed data drives` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked - overridden per user decision) </xhtml:em>
          <xhtml:code>Configure storage of BitLocker recovery information to AD DS</xhtml:code> -&gt; <xhtml:strong>Backup recovery passwords and key packages</xhtml:strong>
          <xhtml:em> `Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked - overridden to enforce AD backup) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure use of hardware-based encryption for fixed data drives</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Configure use of passwords for fixed data drives` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure use of smart cards on fixed data drives</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> `Require use of smart cards on fixed data drives` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>* (checked)</xhtml:p>
        <xhtml:h5>4. Removable Data Drives</xhtml:h5>
        <xhtml:p>Navigate to <xhtml:code>Removable Data Drives</xhtml:code> subfolder: <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow access to BitLocker-protected removable data drives from earlier versions of Windows` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Choose how BitLocker-protected removable drives can be recovered</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> `Allow data recovery agent` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked) </xhtml:em>
          <xhtml:code>Configure user storage of BitLocker recovery information</xhtml:code> -&gt; <xhtml:strong>Do not allow 48-digit recovery password</xhtml:strong>
          <xhtml:em> `Configure user storage of BitLocker recovery key` -&gt; </xhtml:em>
          <xhtml:em>Do not allow 256-bit recovery key</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:code>Omit recovery options from the BitLocker setup wizard</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong> (checked) <xhtml:em> `Save BitLocker recovery information to AD DS for removable data drives` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> (unchecked) </xhtml:em>
          <xhtml:code>Configure storage of BitLocker recovery information to AD DS</xhtml:code> -&gt; <xhtml:strong>Backup recovery passwords and key packages</xhtml:strong>
          <xhtml:em> `Do not enable BitLocker until recovery information is stored to AD DS for removable data drives` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> (unchecked) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure use of hardware-based encryption for removable data drives</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Configure use of passwords for removable data drives` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Configure use of smart cards on removable data drives</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> `Require use of smart cards on removable data drives` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (checked) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Deny write access to removable drives not protected by BitLocker</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> `Do not allow write access to devices configured in another organization` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>* (unchecked)</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to audit and configure BitLocker parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-BitLockerEncryption.ps1">Download Script: Set-BitLockerEncryption.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-BitLockerEncryption.ps1
# Enables BitLocker encryption locally, configures startup policies/PIN lengths, and backs up recovery keys to AD.

Write-Host "--- Enforcing BitLocker Drive Encryption ---" -ForegroundColor Cyan

# 1. Configure FVE Registry settings
$FveRegPath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FveRegPath)) {
    New-Item -Path $FveRegPath -Force | Out-Null
}

# General Startup and Network Unlock settings
Set-ItemProperty -Path $FveRegPath -Name "AllowNetworkUnlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "MinimumPIN" -Value 6 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPM" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMPIN" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMKey" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMKeyPIN" -Value 2 -Type DWord -Force

# OS Drive Settings (18.10.10.2.x)
Set-ItemProperty -Path $FveRegPath -Name "UseEnhancedPin" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSAllowSecureBootForIntegrity" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSManageDRA" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecoveryPassword" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecoveryKey" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSActiveDirectoryBackup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRequireActiveDirectoryBackup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseAdvancedStartup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "EnableBDEWithNoTPM" -Value 0 -Type DWord -Force

# Fixed Drive Settings (18.10.10.1.x)
Set-ItemProperty -Path $FveRegPath -Name "FDVDiscoveryVolumeType" -Value "" -Type String -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVManageDRA" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecoveryPassword" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecoveryKey" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVActiveDirectoryBackup" -Value 1 -Type DWord -Force  # Overridden to enable AD backups
Set-ItemProperty -Path $FveRegPath -Name "FDVActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRequireActiveDirectoryBackup" -Value 1 -Type DWord -Force  # Overridden to require AD backups
Set-ItemProperty -Path $FveRegPath -Name "FDVHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVAllowUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVEnforceUserCert" -Value 1 -Type DWord -Force

# Removable Drive Settings (18.10.10.3.x)
Set-ItemProperty -Path $FveRegPath -Name "RDVDiscoveryVolumeType" -Value "" -Type String -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVManageDRA" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecoveryPassword" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecoveryKey" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVActiveDirectoryBackup" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRequireActiveDirectoryBackup" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVAllowUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVEnforceUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord -Force

# Removable Drive Write Blocks (System FVE Policies)
$FveSystemPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FveSystemPath)) {
    New-Item -Path $FveSystemPath -Force | Out-Null
}
Set-ItemProperty -Path $FveSystemPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord -Force

Write-Host "[+] BitLocker startup authentication and volume encryption policies configured." -ForegroundColor Green

# 2. Enable BitLocker on C: drive using TPM protection
$Volume = Get-BitLockerVolume -MountPoint "C:"

# Check if protection is already active
if ($Volume.ProtectionStatus -eq "Off") {
    Write-Host "[+] Activating BitLocker on C: drive using XTS-AES 256 encryption..." -ForegroundColor Gray
    
    # Enable BitLocker and backup recovery password protector to Active Directory
    Enable-BitLocker -MountPoint "C:" `
        -EncryptionMethod XtsAes256 `
        -UsedSpaceOnly `
        -TpmProtector `
        -AdBackupRequired
        
    Write-Host "[+] BitLocker encryption initiated. Recovery key backed up to AD." -ForegroundColor Green
} else {
    Write-Host "[+] BitLocker is already enabled on C: (Protection Status: $($Volume.ProtectionStatus))." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local BitLocker and Network Unlock registry settings:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-BitLockerStatus.ps1">Download Script: Test-BitLockerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-BitLockerStatus.ps1
# Audits current BitLocker protection state, key protector types, and Network Unlock/Startup PIN configuration.

Write-Host "--- Auditing BitLocker Status ---" -ForegroundColor Cyan

# 1. Query local BitLocker state
$Volume = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue
if ($Volume) {
    $StatusColor = if ($Volume.ProtectionStatus -eq "On") { "Green" } else { "Red" }
    Write-Host "    - Protection Status: $($Volume.ProtectionStatus)" -ForegroundColor $StatusColor
    Write-Host "    - Encryption Method: $($Volume.EncryptionMethod)" -ForegroundColor White
    
    Write-Host "`n[+] Active Key Protectors:" -ForegroundColor Yellow
    foreach ($Protector in $Volume.KeyProtector) {
        Write-Host "    - Type: $($Protector.KeyProtectorType) | ID: $($Protector.KeyProtectorId)" -ForegroundColor White
    }
} else {
    Write-Error "BitLocker volume information could not be retrieved."
}

# 2. Check Network Unlock and Startup Authentication registry configuration
$FveRegPath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
$FveSysPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"

$Params = @(
    @{ Name = "AllowNetworkUnlock"; Expected = 1; Path = $FveRegPath },
    @{ Name = "MinimumPIN"; Expected = 6; Path = $FveRegPath },
    @{ Name = "UseTPM"; Expected = 2; Path = $FveRegPath },
    @{ Name = "UseTPMPIN"; Expected = 2; Path = $FveRegPath },
    @{ Name = "UseTPMKey"; Expected = 2; Path = $FveRegPath },
    @{ Name = "UseTPMKeyPIN"; Expected = 2; Path = $FveRegPath },
    
    # OS Drives
    @{ Name = "UseEnhancedPin"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSAllowSecureBootForIntegrity"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSRecovery"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSManageDRA"; Expected = 0; Path = $FveRegPath },
    @{ Name = "OSRecoveryPassword"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSRecoveryKey"; Expected = 0; Path = $FveRegPath },
    @{ Name = "OSHideRecoveryPage"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSActiveDirectoryBackup"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSActiveDirectoryInfoToStore"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSRequireActiveDirectoryBackup"; Expected = 1; Path = $FveRegPath },
    @{ Name = "OSHardwareEncryption"; Expected = 0; Path = $FveRegPath },
    @{ Name = "OSPassphrase"; Expected = 0; Path = $FveRegPath },
    @{ Name = "UseAdvancedStartup"; Expected = 1; Path = $FveRegPath },
    @{ Name = "EnableBDEWithNoTPM"; Expected = 0; Path = $FveRegPath },
    
    # Fixed Drives
    @{ Name = "FDVDiscoveryVolumeType"; Expected = ""; Path = $FveRegPath },
    @{ Name = "FDVRecovery"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVManageDRA"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVRecoveryPassword"; Expected = 2; Path = $FveRegPath },
    @{ Name = "FDVRecoveryKey"; Expected = 2; Path = $FveRegPath },
    @{ Name = "FDVHideRecoveryPage"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVActiveDirectoryBackup"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVActiveDirectoryInfoToStore"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVRequireActiveDirectoryBackup"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVHardwareEncryption"; Expected = 0; Path = $FveRegPath },
    @{ Name = "FDVPassphrase"; Expected = 0; Path = $FveRegPath },
    @{ Name = "FDVAllowUserCert"; Expected = 1; Path = $FveRegPath },
    @{ Name = "FDVEnforceUserCert"; Expected = 1; Path = $FveRegPath },
    
    # Removable Drives
    @{ Name = "RDVDiscoveryVolumeType"; Expected = ""; Path = $FveRegPath },
    @{ Name = "RDVRecovery"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVManageDRA"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVRecoveryPassword"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVRecoveryKey"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVHideRecoveryPage"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVActiveDirectoryBackup"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVActiveDirectoryInfoToStore"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVRequireActiveDirectoryBackup"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVHardwareEncryption"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVPassphrase"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVAllowUserCert"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVEnforceUserCert"; Expected = 1; Path = $FveRegPath },
    @{ Name = "RDVDenyCrossOrg"; Expected = 0; Path = $FveRegPath },
    @{ Name = "RDVDenyWriteAccess"; Expected = 1; Path = $FveSysPath }
)

Write-Host "`n[*] Auditing BitLocker settings:" -ForegroundColor Yellow
$script:Vulnerable = $false

foreach ($Param in $Params) {
    if (Test-Path $Param.Path) {
        $Val = Get-ItemProperty -Path $Param.Path -Name $Param.Name -ErrorAction SilentlyContinue
        $ActualVal = if ($Val) { $Val.$($Param.Name) } else { $null }
        
        $IsMatch = $false
        if ($Param.Expected -eq "") {
            $IsMatch = ($null -eq $ActualVal -or $ActualVal -eq "")
        } else {
            $IsMatch = ($ActualVal -eq $Param.Expected)
        }
        
        $Color = if ($IsMatch) { "Green" } else { "Red" }
        if (-not $IsMatch) { $script:Vulnerable = $true }
        
        Write-Host "    - $($Param.Name): $ActualVal (Expected = $($Param.Expected))" -ForegroundColor $Color
    } else {
        Write-Host "    - Policy key $($Param.Path) does not exist." -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-BitLockerEncryption.ps1
# Enables BitLocker encryption locally, configures startup policies/PIN lengths, and backs up recovery keys to AD.

Write-Host "--- Enforcing BitLocker Drive Encryption ---" -ForegroundColor Cyan

# 1. Configure FVE Registry settings
$FveRegPath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FveRegPath)) {
    New-Item -Path $FveRegPath -Force | Out-Null
}

# General Startup and Network Unlock settings
Set-ItemProperty -Path $FveRegPath -Name "AllowNetworkUnlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "MinimumPIN" -Value 6 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPM" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMPIN" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMKey" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseTPMKeyPIN" -Value 2 -Type DWord -Force

# OS Drive Settings (18.10.10.2.x)
Set-ItemProperty -Path $FveRegPath -Name "UseEnhancedPin" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSAllowSecureBootForIntegrity" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSManageDRA" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecoveryPassword" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRecoveryKey" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSActiveDirectoryBackup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSRequireActiveDirectoryBackup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "OSPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "UseAdvancedStartup" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "EnableBDEWithNoTPM" -Value 0 -Type DWord -Force

# Fixed Drive Settings (18.10.10.1.x)
Set-ItemProperty -Path $FveRegPath -Name "FDVDiscoveryVolumeType" -Value "" -Type String -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVManageDRA" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecoveryPassword" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRecoveryKey" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVActiveDirectoryBackup" -Value 1 -Type DWord -Force  # Overridden to enable AD backups
Set-ItemProperty -Path $FveRegPath -Name "FDVActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVRequireActiveDirectoryBackup" -Value 1 -Type DWord -Force  # Overridden to require AD backups
Set-ItemProperty -Path $FveRegPath -Name "FDVHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVAllowUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "FDVEnforceUserCert" -Value 1 -Type DWord -Force

# Removable Drive Settings (18.10.10.3.x)
Set-ItemProperty -Path $FveRegPath -Name "RDVDiscoveryVolumeType" -Value "" -Type String -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecovery" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVManageDRA" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecoveryPassword" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRecoveryKey" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVHideRecoveryPage" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVActiveDirectoryBackup" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVActiveDirectoryInfoToStore" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVRequireActiveDirectoryBackup" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVHardwareEncryption" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVPassphrase" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVAllowUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVEnforceUserCert" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $FveRegPath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord -Force

# Removable Drive Write Blocks (System FVE Policies)
$FveSystemPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FveSystemPath)) {
    New-Item -Path $FveSystemPath -Force | Out-Null
}
Set-ItemProperty -Path $FveSystemPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord -Force

Write-Host "[+] BitLocker startup authentication and volume encryption policies configured." -ForegroundColor Green

# 2. Enable BitLocker on C: drive using TPM protection
$Volume = Get-BitLockerVolume -MountPoint "C:"

# Check if protection is already active
if ($Volume.ProtectionStatus -eq "Off") {
    Write-Host "[+] Activating BitLocker on C: drive using XTS-AES 256 encryption..." -ForegroundColor Gray
    
    # Enable BitLocker and backup recovery password protector to Active Directory
    Enable-BitLocker -MountPoint "C:" `
        -EncryptionMethod XtsAes256 `
        -UsedSpaceOnly `
        -TpmProtector `
        -AdBackupRequired
        
    Write-Host "[+] BitLocker encryption initiated. Recovery key backed up to AD." -ForegroundColor Green
} else {
    Write-Host "[+] BitLocker is already enabled on C: (Protection Status: $($Volume.ProtectionStatus))." -ForegroundColor Green
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8012" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-013" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-013] UEFI Firmware Security Hardening</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-005](../07-paws/configure-uefi-security.md); for Domain Controllers, refer to [REQ-DC-157](../02-domain-controllers/configure-uefi-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-uefi-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Standard Tier 2 endpoints (such as corporate laptops and desktop workstations) and member servers are frequently exposed to physical theft, unauthorized local access in branch offices, or untrusted local networks. If system firmware remains unconfigured or relies on legacy BIOS modes, attackers can alter boot settings, subvert operating system security features, bypass disk encryption, or execute physical DMA and bootkit attacks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Manual UEFI Firmware Configuration (Preferred)</xhtml:h3>
        <xhtml:p>UEFI settings must be configured directly within the hardware platform firmware interface during system startup.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Turn on or restart the workstation and access the UEFI utility screen by pressing the vendor-specific key during POST (typically Delete, F2, F10, or F12).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Authentication</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Select the option to set the </xhtml:em>
            <xhtml:em>Administrator Password</xhtml:em>
            <xhtml:em> (also referred to as the </xhtml:em>
            <xhtml:em>Supervisor Password</xhtml:em>*). Do not configure a User Password, as that prompts for authentication on every boot rather than only when entering configuration settings.</xhtml:li>
          <xhtml:li>* Enter a strong, complex password. Record this password in the enterprise credential vault.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Boot</xhtml:strong> or <xhtml:strong>System Configuration</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate the </xhtml:em>
            <xhtml:em>Boot Mode</xhtml:em>
            <xhtml:em> setting and set it to </xhtml:em>
            <xhtml:em>UEFI Only</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Native UEFI</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>CSM (Compatibility Support Module)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Legacy Boot Support</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Fast Boot</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Quick Boot</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>* (forcing complete POST diagnostics and full TPM initialization on every boot).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Boot Order</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Boot Priority</xhtml:em>*):</xhtml:li>
          <xhtml:li>* Set the primary boot option to the internal system storage drive (typically containing the Windows Boot Manager partition).</xhtml:li>
          <xhtml:li>* Disable unauthorized external boot devices (such as optical drives and unauthorized USB boot) or require the administrator password to boot from alternate media.</xhtml:li>
          <xhtml:li>* Enable the option to prompt for the UEFI administrator password if a user attempts to access the boot override menu (typically F12 or F8).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Advanced</xhtml:strong>, <xhtml:strong>CPU Configuration</xhtml:strong>, or <xhtml:strong>Security Chip</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Intel Virtualization Technology (VT-x)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD-V</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>Intel VT for Directed I/O (VT-d)</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>AMD IOMMU</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (required for IOMMU/Kernel DMA Protection).</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate </xhtml:em>
            <xhtml:em>TPM 2.0 Device</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Security Chip / Intel PTT / AMD fTPM</xhtml:em>
            <xhtml:em>) and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Active</xhtml:em>* (with SHA-256 PCR bank).</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Security</xhtml:strong> or <xhtml:strong>Secure Boot</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Ensure </xhtml:em>
            <xhtml:em>Secure Boot</xhtml:em>
            <xhtml:em> is </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> and the </xhtml:em>
            <xhtml:em>Secure Boot Mode</xhtml:em>
            <xhtml:em> is set to </xhtml:em>
            <xhtml:em>Deployed</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>User Mode</xhtml:em>*.</xhtml:li>
          <xhtml:li>Navigate to the <xhtml:strong>Advanced</xhtml:strong> or <xhtml:strong>Firmware Update</xhtml:strong> section:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Locate the option for </xhtml:em>
            <xhtml:em>BIOS Flash Protection</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Firmware Rollback Protection</xhtml:em>
            <xhtml:em> and set it to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> or </xhtml:em>
            <xhtml:em>Block Downgrades</xhtml:em>*.</xhtml:li>
          <xhtml:li>Save the configuration and restart the workstation.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell Remediation &amp; OS Boot Hardening</xhtml:h3>
        <xhtml:p>Run the following script to configure OS-level boot parameters (disabling Windows Fast Startup, ensuring Device Guard platform flags), detect the hardware vendor, and provide enterprise OEM automation commands.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-UEFISecurity.ps1">Download Script: Set-UEFISecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-UEFISecurity.ps1
# Description: Configures OS-level boot parameters and audits OEM firmware configuration for endpoints and member servers.

Write-Host "--- Configuring Endpoint UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features configured (Value = 1)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Hardware OEM and report vendor tooling commands
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue
Write-Host "`nOEM Firmware Detection:" -ForegroundColor Cyan
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($Bios.Manufacturer -match "Dell") {
    Write-Host "  [i] Dell Platform detected. Enterprise configuration via Dell Command | PowerShell Provider:" -ForegroundColor Yellow
    Write-Host "      Import-Module DellBIOSProvider" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Boot\BootMode 'UEFI'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\SecureBoot\SecureBoot 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\Virtualization 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\VtForDirectIO 'Enabled'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "HP") {
    Write-Host "  [i] HP Platform detected. Enterprise configuration via HP Client Management Script Library (HPCMSL):" -ForegroundColor Yellow
    Write-Host "      Import-Module HPCMSL" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Boot Mode' -Value 'UEFI Native (without CSM)'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Secure Boot' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology' -Value 'Enable'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "Lenovo") {
    Write-Host "  [i] Lenovo Platform detected. Enterprise configuration via Lenovo BIOS WMI interface:" -ForegroundColor Yellow
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('BootMode,UEFI')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('SecureBoot,Enable')" -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-UEFISecurity.ps1
# Description: Configures OS-level boot parameters and audits OEM firmware configuration for endpoints and member servers.

Write-Host "--- Configuring Endpoint UEFI &amp; Boot Security Baseline ---" -ForegroundColor Cyan

# 1. Disable Windows Fast Startup (forces full cold boot and fresh TPM PCR measurements)
$PowerPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
if (-not (Test-Path $PowerPath)) {
    New-Item -Path $PowerPath -Force | Out-Null
}

try {
    Set-ItemProperty -Path $PowerPath -Name "HiberbootEnabled" -Value 0 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Windows Fast Startup disabled (HiberbootEnabled = 0)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure HiberbootEnabled: $($_.Exception.Message)" -ForegroundColor Red
}

# 2. Configure Device Guard Platform Security Flags
$DeviceGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
if (-not (Test-Path $DeviceGuardPath)) {
    New-Item -Path $DeviceGuardPath -Force | Out-Null
}

try {
    # 1 = Secure Boot, 3 = Secure Boot and DMA Protection
    Set-ItemProperty -Path $DeviceGuardPath -Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord -Force -ErrorAction Stop
    Write-Host "[+] Device Guard required platform security features configured (Value = 1)." -ForegroundColor Green
} catch {
    Write-Host "[!] Failed to configure RequirePlatformSecurityFeatures: $($_.Exception.Message)" -ForegroundColor Red
}

# 3. Detect Hardware OEM and report vendor tooling commands
$Bios = Get-CimInstance -ClassName Win32_Bios -ErrorAction SilentlyContinue
Write-Host "`nOEM Firmware Detection:" -ForegroundColor Cyan
Write-Host "  Manufacturer: $($Bios.Manufacturer)" -ForegroundColor White
Write-Host "  BIOS Version: $($Bios.SMBIOSBIOSVersion)" -ForegroundColor White

if ($Bios.Manufacturer -match "Dell") {
    Write-Host "  [i] Dell Platform detected. Enterprise configuration via Dell Command | PowerShell Provider:" -ForegroundColor Yellow
    Write-Host "      Import-Module DellBIOSProvider" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\Boot\BootMode 'UEFI'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\SecureBoot\SecureBoot 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\Virtualization 'Enabled'" -ForegroundColor Gray
    Write-Host "      Set-Item -Path DellSmbios:\VirtualizationSupport\VtForDirectIO 'Enabled'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "HP") {
    Write-Host "  [i] HP Platform detected. Enterprise configuration via HP Client Management Script Library (HPCMSL):" -ForegroundColor Yellow
    Write-Host "      Import-Module HPCMSL" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Boot Mode' -Value 'UEFI Native (without CSM)'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Secure Boot' -Value 'Enable'" -ForegroundColor Gray
    Write-Host "      Set-HPBIOSSettingValue -Name 'Virtualization Technology' -Value 'Enable'" -ForegroundColor Gray
} elseif ($Bios.Manufacturer -match "Lenovo") {
    Write-Host "  [i] Lenovo Platform detected. Enterprise configuration via Lenovo BIOS WMI interface:" -ForegroundColor Yellow
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('BootMode,UEFI')" -ForegroundColor Gray
    Write-Host "      (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting('SecureBoot,Enable')" -ForegroundColor Gray
}

Write-Host "`n[+] Remediation script completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8013" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-014" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-014] Enable Hardware Virtualization and DMA Protection</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (version 1803 and above) Enterprise/Professional, Windows 11 Enterprise/Professional, Windows Server 2019 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-hardware-virtualization-and-dma-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Direct Memory Access (DMA) allows hardware devices to read and write directly to physical system memory (RAM) over high-speed buses without CPU or operating system arbitration. External expansion ports—such as Thunderbolt 3, Thunderbolt 4, USB4, and hot-plug PCIe slots—expose internal PCI Express lanes directly to external peripherals.</xhtml:p>
        <xhtml:p>If external DMA interfaces are left unprotected, an attacker with physical access to an unattended, locked, or stolen endpoint can connect malicious hardware tools or implants (such as PCILeech or USB3380 DMA attack adapters) to perform drive-by physical DMA attacks. Through unrestricted DMA access, attackers can extract sensitive secrets directly from RAM—including BitLocker full-volume encryption keys, DPAPI master keys, LSASS authentication tokens, Kerberos tickets, and cached credentials—or write to memory to inject kernel payloads and bypass Windows lock screens.</xhtml:p>
        <xhtml:p>Configuring Kernel DMA Protection and enforcing strict external device enumeration mitigates this threat vector: 1. <xhtml:strong>IOMMU Memory Isolation</xhtml:strong>: Kernel DMA Protection utilizes the system's Input-Output Memory Management Unit (IOMMU: Intel VT-d or AMD-Vi) and ACPI DMAR tables to create hypervisor-enforced memory sandboxes for peripheral devices. For DMA-remapping-compatible devices, the operating system isolates device DMA transfers exclusively to the specific memory buffers allocated to that device's driver, blocking unauthorized access to adjacent physical RAM. 2. <xhtml:strong>Mitigating Incompatible External Devices</xhtml:strong>: External devices and drivers are classified into two categories: those that support DMA remapping and those that do not. If an incompatible or rogue peripheral without DMA-remapping support is connected, Windows default behavior may permit enumeration or delay it until user login. Setting the enumeration policy to <xhtml:strong>Block All</xhtml:strong> (<xhtml:code>DeviceEnumerationPolicy = 0</xhtml:code>) guarantees that any external device whose drivers do not explicitly support DMA remapping is unconditionally blocked from initializing, loading drivers, or executing DMA transfers. 3. <xhtml:strong>Closing the Physical Hot-Plug Attack Surface</xhtml:strong>: By blocking incompatible external DMA devices, the operating system ensures that only verified, DMA-remapping-compliant peripherals operate under strict hypervisor IOMMU containment, preventing drive-by memory dumping attacks while preserving device functionality for certified hardware.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce the Kernel DMA Protection external device enumeration policy across standard client workstations and member servers, implement the following GPO settings:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the target workstations and member servers OUs (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Enumeration policy for external devices incompatible with Kernel DMA Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enumeration policy</xhtml:em>
            <xhtml:em>: Select </xhtml:em>
            <xhtml:em>Block All</xhtml:em>* (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate OUs.</xhtml:li>
        </xhtml:ol>
        <xhtml:p>
          <xhtml:em>Note: For Kernel DMA Protection to operate with maximum security, ensure platform hardware virtualization and IOMMU extensions (Intel VT-d or AMD-Vi) are enabled in the UEFI configuration menu as outlined in [REQ-END-013 - UEFI Firmware Security Hardening](configure-uefi-security.md).</xhtml:em>
        </xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure local registry keys to enforce Kernel DMA Protection and programmatically audit the hardware security baseline.</xhtml:p>
        <xhtml:h4>1. Local Remediation (Enforce Kernel DMA Protection)</xhtml:h4>
        <xhtml:p>Run the following script to configure the Kernel DMA Protection policy locally:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-KernelDMAProtection.ps1">Download Script: Configure-KernelDMAProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-KernelDMAProtection.ps1
# Description: Configures registry keys to enable Kernel DMA Protection and block incompatible external DMA devices.

Write-Host "--- Enforcing Kernel DMA Protection ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path -Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# DeviceEnumerationPolicy = 0 (Block all external DMA devices incompatible with Kernel DMA Protection)
Set-ItemProperty -Path $RegPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "Status: Kernel DMA Protection registry configuration applied (DeviceEnumerationPolicy = 0 [Block All])." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:h4>2. Local Audit (Kernel DMA Protection, IOMMU, and Hardware Baseline)</xhtml:h4>
        <xhtml:p>Run the following script to audit the status of Kernel DMA Protection, IOMMU support, and the required hardware security components:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-HardwareSecurityFeatures.ps1">Download Script: Audit-HardwareSecurityFeatures.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-HardwareSecurityFeatures.ps1
# Description: Audits Kernel DMA Protection registry policy, hardware IOMMU/DMA status, VBS state, and TPM readiness.

Write-Host "--- Auditing Kernel DMA Protection and Hardware Security Baseline ---" -ForegroundColor Cyan

# 1. Audit Kernel DMA Protection Registry Policy
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
$EnumPolicy = Get-ItemProperty -Path $RegPath -Name "DeviceEnumerationPolicy" -ErrorAction SilentlyContinue

if ($null -ne $EnumPolicy -and $EnumPolicy.DeviceEnumerationPolicy -eq 0) {
    Write-Host "Status: Kernel DMA Protection Policy (DeviceEnumerationPolicy): 0 (Block All) [COMPLIANT]" -ForegroundColor Green
} else {
    $CurrentVal = if ($null -ne $EnumPolicy) { $EnumPolicy.DeviceEnumerationPolicy } else { "Not Configured" }
    Write-Host "VULNERABLE: Kernel DMA Protection Policy is '$($CurrentVal)'. Expected: 0 (Block All)." -ForegroundColor Red
}

# 2. Audit VBS and Hardware DMA/IOMMU Status via Win32_DeviceGuard
try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    
    # VirtualizationBasedSecurityStatus: 2 = Running
    $VbsStatus = $DG.VirtualizationBasedSecurityStatus
    if ($VbsStatus -eq 2) {
        Write-Host "Status: Virtualization-Based Security (VBS) Status: 2 (Running) [COMPLIANT]" -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Virtualization-Based Security (VBS) is not running (Status: $($VbsStatus))." -ForegroundColor Red
    }
    
    # AvailableSecurityProperties: 3 = DMA Protection (IOMMU)
    $DmaSupported = $DG.AvailableSecurityProperties -contains 3
    if ($DmaSupported -eq $true) {
        Write-Host "Status: Hardware IOMMU / DMA Remapping Support: True [COMPLIANT]" -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: Hardware IOMMU / DMA Protection is not available on this platform." -ForegroundColor Red
    }
    
    # RequiredSecurityProperties: 3 = DMA Protection enforced
    $DmaEnforced = $DG.RequiredSecurityProperties -contains 3
    if ($DmaEnforced -eq $true) {
        Write-Host "Status: DMA Protection Security Policy Enforced: True [COMPLIANT]" -ForegroundColor Green
    } else {
        Write-Host "Status: DMA Protection Security Policy Enforced: False [INFO]" -ForegroundColor Yellow
    }
} catch {
    Write-Host "VULNERABLE: Win32_DeviceGuard WMI class could not be queried. VBS / Device Guard is inactive." -ForegroundColor Red
}

# 3. Audit TPM 2.0 Status
$Tpm = Get-Tpm -ErrorAction SilentlyContinue
if ($null -ne $Tpm) {
    if ($Tpm.TpmPresent -eq $true -and $Tpm.TpmReady -eq $true) {
        Write-Host "Status: TPM 2.0 Present: True | Ready: True [COMPLIANT]" -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: TPM Present: $($Tpm.TpmPresent) | Ready: $($Tpm.TpmReady) (Expected: Present and Ready)." -ForegroundColor Red
    }
} else {
    Write-Host "VULNERABLE: TPM verification cmdlet failed." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-KernelDMAProtection.ps1
# Description: Configures registry keys to enable Kernel DMA Protection and block incompatible external DMA devices.

Write-Host "--- Enforcing Kernel DMA Protection ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path -Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

# DeviceEnumerationPolicy = 0 (Block all external DMA devices incompatible with Kernel DMA Protection)
Set-ItemProperty -Path $RegPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "Status: Kernel DMA Protection registry configuration applied (DeviceEnumerationPolicy = 0 [Block All])." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8014" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-015" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-015] Disable Windows Platform Binary Table (WPBT)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/disable-wpbt.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Platform Binary Table (WPBT) is an ACPI firmware table that allows hardware manufacturers (OEMs) to execute proprietary binaries in kernel space during the Windows boot phase. Windows automatically extracts the binary from the table and runs it with system privileges before security software, third-party agents, or standard driver verifications are fully initialized.</xhtml:p>
        <xhtml:p>While designed to facilitate automated driver provisioning and anti-theft services, this mechanism represents a significant security risk: 1. <xhtml:strong>Firmware-to-OS Attack Vector</xhtml:strong>: Malicious actors utilizing UEFI rootkits, physical firmware flashing tools, or supply-chain firmware implants can compromise the WPBT table to execute arbitrary code at boot, bypassing Secure Boot and operating system-level integrity checks. 2. <xhtml:strong>Privilege Escalation Risks</xhtml:strong>: Historically, OEM software delivered via the WPBT has introduced high-severity local privilege escalation and remote code execution vulnerabilities due to inadequate code review or poor permission management. 3. <xhtml:strong>Control and Transparency</xhtml:strong>: Executing firmware-rooted binaries without administrative visibility or operating system validation bypasses normal software lifecycle and endpoint protection policies.</xhtml:p>
        <xhtml:p>Disabling WPBT execution prevents Windows from parsing the ACPI table and running the embedded software, mitigating boot-level integrity bypasses.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Because there is no default ADMX administrative template to manage WPBT execution, the setting must be configured as a Registry Preference under the endpoint policy:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
          <xhtml:li>Edit the GPO linked to your workstations Organizational Unit (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New -&gt; Registry Item</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the following properties:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>DisableWpbtExecution</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>OK</xhtml:strong> to save the preference.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script to configure the registry setting locally on the system:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableWpbt.ps1">Download Script: Configure-DisableWpbt.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableWpbt.ps1
# Description: Disables Windows Platform Binary Table (WPBT) execution in the registry.

Write-Host "Applying hardening requirement: Disable WPBT Execution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "Registry setting DisableWpbtExecution configured to 1." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify that the registry value is correctly enforced:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-WpbtStatus.ps1">Download Script: Get-WpbtStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WpbtStatus.ps1
# Description: Audits the registry state for WPBT execution prevention.

Write-Host "--- Auditing WPBT Security Posture ---" -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"

$RegistryValue = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue

if ($RegistryValue) {
    $Setting = $RegistryValue.DisableWpbtExecution
    if ($Setting -eq 1) {
        Write-Host "Status: WPBT execution is disabled (DisableWpbtExecution = 1)." -ForegroundColor Green
    } else {
        Write-Host "VULNERABLE: WPBT execution is enabled. Value is $($Setting)." -ForegroundColor Red
    }
} else {
    Write-Host "VULNERABLE: DisableWpbtExecution registry value is not configured (defaulting to execution enabled)." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWpbt.ps1
# Description: Disables Windows Platform Binary Table (WPBT) execution in the registry.

Write-Host "Applying hardening requirement: Disable WPBT Execution..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "DisableWpbtExecution"
$ValueData = 1

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord
Write-Host "Registry setting DisableWpbtExecution configured to 1." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8015" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-017" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-017] Harden DMA and Physical Security</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Member Servers, Tier 2 Clients (Workstations / Laptops). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-011](../07-paws/harden-dma-and-physical-security.md); for Domain Controllers, refer to [REQ-DC-158](../02-domain-controllers/harden-dma-and-physical-security.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/harden-dma-and-physical-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Physical access to an endpoint introduces distinct attack vectors that bypass traditional OS privilege separation:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Direct Memory Access (DMA) Attacks</xhtml:strong>: Hot-plug buses (such as FireWire, Thunderbolt, and USB4) permit connected peripherals to read and write directly to system memory without operating system mediation. Attackers connect specialized hardware (e.g., PCILeech) to exposed external ports to extract BitLocker encryption keys, NTLM hashes, or active session tokens directly from RAM:</xhtml:li>
          <xhtml:li>* Disabling the Serial Bus Protocol 2 (SBP-2) setup class (<xhtml:code>{d48179be-ec20-11d1-b6b8-00c04fa372a7}</xhtml:code>) blocks FireWire/IEEE 1394 DMA controllers.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Blocking hardware device IDs `PCI\CC_0C0A` (Thunderbolt) and `PCI\CC_0C0010` (1394 OHCI FireWire) halts driver initialization for dangerous hot-plug controllers. </xhtml:em>(Note: On Tier 0 PAWs, additional legacy controller setup classes and CardBus/PCMCIA bridges are blocked under <xhtml:a href="../07-paws/harden-dma-and-physical-security.md">REQ-PAW-011</xhtml:a>).*</xhtml:li>
          <xhtml:li>* Enforcing <xhtml:code>DisableExternalDMAUnderLock</xhtml:code> prevents DMA requests while the workstation screen is locked.</xhtml:li>
          <xhtml:li>
            <xhtml:em> `DeviceEnumerationPolicy` set to </xhtml:em>
            <xhtml:em>Block all</xhtml:em>* (0) ensures devices lacking DMA-remapping isolation support cannot execute unauthorized memory access transfers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Cold Boot Attacks &amp; Sleep Vulnerabilities</xhtml:strong>: When an endpoint enters standby sleep states (S1-S3), system RAM remains powered and active. If an unattended laptop or desktop is stolen while in standby, an attacker can quickly reboot the machine or chill the DRAM chips to dump memory contents and retrieve BitLocker keys. Disabling standby forces systems to transition to Hibernation (S4)/Shutdown, where RAM contents are flushed to the BitLocker-encrypted disk and sealed by the TPM. Enforcing a password upon wake prevents unauthorized physical resumption.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>USB Data Exfiltration</xhtml:strong>: Blocking write access to removable drives unless they are encrypted with BitLocker (<xhtml:code>RDVDenyWriteAccess</xhtml:code>) prevents users or malicious agents from copying confidential organizational data to unauthorized, unencrypted USB media. Setting <xhtml:code>RDVDenyCrossOrg = 0</xhtml:code> enforces organization-wide BitLocker compliance.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO targeting endpoints (e.g., <xhtml:code>GPO_Hardening_DMA_Physical</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>1. Power Management (Disable Standby &amp; Require Wake Password)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Power Management\Sleep Settings</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Allow standby states (S1-S3) when sleeping (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Disabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Allow standby states (S1-S3) when sleeping (on battery)</xhtml:code> -&gt; <xhtml:strong>Disabled</xhtml:strong>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Require a password when a computer wakes (plugged in)` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Require a password when a computer wakes (on battery)</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
        </xhtml:p>
        <xhtml:h4>2. BitLocker Removable Storage &amp; DMA</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Disable new DMA devices when this computer is locked` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em />
        </xhtml:p>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption\Removable Data Drives</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Deny write access to removable drives not protected by BitLocker` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Check <xhtml:strong>Do not allow write access to devices configured in another organization</xhtml:strong> -&gt; <xhtml:strong>Disabled</xhtml:strong> (value 0 / False)</xhtml:p>
        <xhtml:h4>3. Device Installation Restrictions (Block SBP-2 Setup Class &amp; PCI Device IDs)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Device Installation\Device Installation Restrictions</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Prevent installation of devices using drivers that match these device setup classes` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em> Click <xhtml:strong>Show...</xhtml:strong> and enter: <xhtml:code>{d48179be-ec20-11d1-b6b8-00c04fa372a7}</xhtml:code>
          <xhtml:em> Check </xhtml:em>
          <xhtml:em>Also apply to matching devices that are already installed</xhtml:em>
          <xhtml:em> -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> (value 1 / True) </xhtml:em>
          <xhtml:strong>Policy</xhtml:strong>: <xhtml:code>Prevent installation of devices that match any of these device IDs</xhtml:code> -&gt; <xhtml:strong>Enabled</xhtml:strong>
          <xhtml:em> Click </xhtml:em>
          <xhtml:em>Show...</xhtml:em>
          <xhtml:em> and enter: </xhtml:em>
          <xhtml:code>PCI\CC_0C0A</xhtml:code>
          <xhtml:em> `PCI\CC_0C0010` </xhtml:em> Check <xhtml:strong>Also apply to matching devices that are already installed</xhtml:strong> -&gt; <xhtml:strong>Enabled</xhtml:strong> (value 1 / True)</xhtml:p>
        <xhtml:h4>4. Kernel DMA Protection (Block All)</xhtml:h4>
        <xhtml:p>Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\Kernel DMA Protection</xhtml:code>
          <xhtml:em> </xhtml:em>
          <xhtml:em>Policy</xhtml:em>
          <xhtml:em>: `Enable Kernel DMA Protection` -&gt; </xhtml:em>
          <xhtml:em>Enabled</xhtml:em>
          <xhtml:em> </xhtml:em>
          <xhtml:strong>Enumeration policy</xhtml:strong>: Set to <xhtml:strong>Block all</xhtml:strong> (value 0)</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to apply DMA, Sleep, Device Restriction, and BitLocker USB registry parameters.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-DMAPhysicalSecurity.ps1">Download Script: Set-DMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-DMAPhysicalSecurity.ps1
# Description: Hardens local registry keys to mitigate DMA attacks, disable standby sleep states, enforce wake password, and restrict unencrypted USB writing.

Write-Host "Applying DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Block SBP-2 class and PCI device IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String

$DenyIDPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIDPath)) {
    New-Item -Path $DenyIDPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIDPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIDPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Write-Host "[+] Device installation blocks for SBP-2 class, PCI\CC_0C0A, and PCI\CC_0C0010 enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "DMA and physical security settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit local DMA and physical security configuration:</xhtml:em>
          <xhtml:a href="audit_scripts/Test-DMAPhysicalSecurity.ps1">Download Script: Test-DMAPhysicalSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-DMAPhysicalSecurity.ps1
# Description: Audits local registry configuration for standby settings, wake password, DMA protection under lock, USB restrictions, and blocked device setup classes/IDs.

Write-Host "--- Auditing DMA and Physical Security ---" -ForegroundColor Cyan
$isCompliant = $true

# 1. Audit Standby Settings
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
$AcSleep = Get-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcSleep = Get-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcSleepVal = if ($AcSleep) { $AcSleep.ACSettingIndex } else { 1 }
$DcSleepVal = if ($DcSleep) { $DcSleep.DCSettingIndex } else { 1 }

$AcSleepColor = if ($AcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }
$DcSleepColor = if ($DcSleepVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Standby Sleep State (Plugged In) Setting: $($AcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $AcSleepColor
Write-Host "    - Standby Sleep State (On Battery) Setting: $($DcSleepVal) (Required = 0 [Disabled])" -ForegroundColor $DcSleepColor

# 2. Audit Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
$AcWake = Get-ItemProperty -Path $WakePath -Name "ACSettingIndex" -ErrorAction SilentlyContinue
$DcWake = Get-ItemProperty -Path $WakePath -Name "DCSettingIndex" -ErrorAction SilentlyContinue

$AcWakeVal = if ($AcWake) { $AcWake.ACSettingIndex } else { 0 }
$DcWakeVal = if ($DcWake) { $DcWake.DCSettingIndex } else { 0 }

$AcWakeColor = if ($AcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }
$DcWakeColor = if ($DcWakeVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Wake Password Required (Plugged In): $($AcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $AcWakeColor
Write-Host "    - Wake Password Required (On Battery): $($DcWakeVal) (Required = 1 [Enabled])" -ForegroundColor $DcWakeColor

# 3. Audit BitLocker Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
$DmaLock = Get-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -ErrorAction SilentlyContinue
$DmaLockVal = if ($DmaLock) { $DmaLock.DisableExternalDMAUnderLock } else { 0 }
$DmaLockColor = if ($DmaLockVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$CrossOrg = Get-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -ErrorAction SilentlyContinue
$CrossOrgVal = if ($CrossOrg) { $CrossOrg.RDVDenyCrossOrg } else { 1 }
$CrossOrgColor = if ($CrossOrgVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
$UsbWrite = Get-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -ErrorAction SilentlyContinue
$UsbWriteVal = if ($UsbWrite) { $UsbWrite.RDVDenyWriteAccess } else { 0 }
$UsbWriteColor = if ($UsbWriteVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Disable DMA Under Lock: $($DmaLockVal) (Required = 1)" -ForegroundColor $DmaLockColor
Write-Host "    - USB Deny Cross Org Removable Drives: $($CrossOrgVal) (Required = 0)" -ForegroundColor $CrossOrgColor
Write-Host "    - USB Unencrypted Write Block: $($UsbWriteVal) (Required = 1)" -ForegroundColor $UsbWriteColor

# 4. Audit Device Restriction Settings
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
$DenyDev = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -ErrorAction SilentlyContinue
$DenyDevVal = if ($DenyDev) { $DenyDev.DenyDeviceClasses } else { 0 }
$DenyDevColor = if ($DenyDevVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

$DenyID = Get-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -ErrorAction SilentlyContinue
$DenyIDVal = if ($DenyID) { $DenyID.DenyDeviceIDs } else { 0 }
$DenyIDColor = if ($DenyIDVal -eq 1) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Prevent Device Setup Class Installation: $($DenyDevVal) (Required = 1)" -ForegroundColor $DenyDevColor
Write-Host "    - Prevent Device ID Installation: $($DenyIDVal) (Required = 1)" -ForegroundColor $DenyIDColor

$DenyClassPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses"
$Sbp2 = Get-ItemProperty -Path $DenyClassPath -Name "1" -ErrorAction SilentlyContinue
$Sbp2Val = if ($Sbp2) { $Sbp2."1" } else { "" }
$Sbp2Color = if ($Sbp2Val -eq "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked SBP-2 Setup Class: '$($Sbp2Val)' (Required = '{d48179be-ec20-11d1-b6b8-00c04fa372a7}')" -ForegroundColor $Sbp2Color

$DenyIDPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs"
$DId1 = Get-ItemProperty -Path $DenyIDPath -Name "1" -ErrorAction SilentlyContinue
$DId1Val = if ($DId1) { $DId1."1" } else { "" }
$DId1Color = if ($DId1Val -eq "PCI\CC_0C0A") { "Green" } else { $isCompliant = $false; "Red" }

$DId2 = Get-ItemProperty -Path $DenyIDPath -Name "2" -ErrorAction SilentlyContinue
$DId2Val = if ($DId2) { $DId2."2" } else { "" }
$DId2Color = if ($DId2Val -eq "PCI\CC_0C0010") { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Blocked Device ID PCI\CC_0C0A: '$($DId1Val)' (Required = 'PCI\CC_0C0A')" -ForegroundColor $DId1Color
Write-Host "    - Blocked Device ID PCI\CC_0C0010: '$($DId2Val)' (Required = 'PCI\CC_0C0010')" -ForegroundColor $DId2Color

# 5. Audit Kernel DMA Protection Setting
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
$EnumPol = Get-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -ErrorAction SilentlyContinue
$EnumPolVal = if ($EnumPol) { $EnumPol.DeviceEnumerationPolicy } else { 2 }
$EnumPolColor = if ($EnumPolVal -eq 0) { "Green" } else { $isCompliant = $false; "Red" }

Write-Host "    - Kernel DMA Protection Policy: $($EnumPolVal) (Required = 0 [Block all])" -ForegroundColor $EnumPolColor

# 6. Final Compliance Assessment
if ($isCompliant) {
    Write-Host "[+] Audit Result: SECURE - Endpoint DMA and physical security controls are fully compliant." -ForegroundColor Green
} else {
    Write-Host "[-] Audit Result: VULNERABLE - One or more endpoint DMA or physical security settings do not meet baseline requirements." -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-DMAPhysicalSecurity.ps1
# Description: Hardens local registry keys to mitigate DMA attacks, disable standby sleep states, enforce wake password, and restrict unencrypted USB writing.

Write-Host "Applying DMA and physical security hardening..." -ForegroundColor Cyan

# 1. Disable Standby Sleep States (S1-S3)
$SleepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab"
if (-not (Test-Path $SleepPath)) {
    New-Item -Path $SleepPath -Force | Out-Null
}
Set-ItemProperty -Path $SleepPath -Name "ACSettingIndex" -Value 0 -Type DWord
Set-ItemProperty -Path $SleepPath -Name "DCSettingIndex" -Value 0 -Type DWord
Write-Host "[+] Standby sleep states (S1-S3) disabled." -ForegroundColor Green

# 2. Configure Wake Password Requirement
$WakePath = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"
if (-not (Test-Path $WakePath)) {
    New-Item -Path $WakePath -Force | Out-Null
}
Set-ItemProperty -Path $WakePath -Name "ACSettingIndex" -Value 1 -Type DWord
Set-ItemProperty -Path $WakePath -Name "DCSettingIndex" -Value 1 -Type DWord
Write-Host "[+] Wake password requirement enforced." -ForegroundColor Green

# 3. BitLocker DMA and Removable Storage Settings
$FvePath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePath)) {
    New-Item -Path $FvePath -Force | Out-Null
}
Set-ItemProperty -Path $FvePath -Name "DisableExternalDMAUnderLock" -Value 1 -Type DWord
Set-ItemProperty -Path $FvePath -Name "RDVDenyCrossOrg" -Value 0 -Type DWord

$FvePolicyPath = "HKLM:\System\CurrentControlSet\Policies\Microsoft\FVE"
if (-not (Test-Path $FvePolicyPath)) {
    New-Item -Path $FvePolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $FvePolicyPath -Name "RDVDenyWriteAccess" -Value 1 -Type DWord
Write-Host "[+] BitLocker DMA under lock and unencrypted USB write blocks configured." -ForegroundColor Green

# 4. Device Installation Restrictions (Block SBP-2 class and PCI device IDs)
$RestrictPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions"
if (-not (Test-Path $RestrictPath)) {
    New-Item -Path $RestrictPath -Force | Out-Null
}
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClasses" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceClassesRetroactive" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDs" -Value 1 -Type DWord
Set-ItemProperty -Path $RestrictPath -Name "DenyDeviceIDsRetroactive" -Value 1 -Type DWord

$DenyClassPath = Join-Path $RestrictPath "DenyDeviceClasses"
if (-not (Test-Path $DenyClassPath)) {
    New-Item -Path $DenyClassPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyClassPath -Name "1" -Value "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" -Type String

$DenyIDPath = Join-Path $RestrictPath "DenyDeviceIDs"
if (-not (Test-Path $DenyIDPath)) {
    New-Item -Path $DenyIDPath -Force | Out-Null
}
Set-ItemProperty -Path $DenyIDPath -Name "1" -Value "PCI\CC_0C0A" -Type String
Set-ItemProperty -Path $DenyIDPath -Name "2" -Value "PCI\CC_0C0010" -Type String
Write-Host "[+] Device installation blocks for SBP-2 class, PCI\CC_0C0A, and PCI\CC_0C0010 enabled." -ForegroundColor Green

# 5. Kernel DMA Protection (Block all external DMA)
$KDmaPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\KernelDMAProtection"
if (-not (Test-Path $KDmaPath)) {
    New-Item -Path $KDmaPath -Force | Out-Null
}
Set-ItemProperty -Path $KDmaPath -Name "DeviceEnumerationPolicy" -Value 0 -Type DWord
Write-Host "[+] Kernel DMA Protection DeviceEnumerationPolicy set to 0 (Block all)." -ForegroundColor Green

Write-Host "DMA and physical security settings applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8017" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-020" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-020] Configure Exploit Protection Profile</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-exploit-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Exploit Protection (the successor to the Enhanced Mitigation Experience Toolkit, or EMET) provides a set of advanced memory and vulnerability mitigations. These mitigations protect both the operating system and applications from memory corruption, buffer overflows, execution redirection, and process hijack attempts.</xhtml:p>
        <xhtml:p>By enforcing system-wide mitigations: 1. <xhtml:strong>Data Execution Prevention (DEP)</xhtml:strong>: Enforces non-executable memory pages, preventing attackers from executing shellcode injected into data-only memory regions (such as the stack or heap). 2. <xhtml:strong>Address Space Layout Randomization (ASLR)</xhtml:strong>: Randomizes the locations where system components, executable code, and memory allocations are loaded. Enabling Mandatory ASLR (Force Relocate Images), Bottom-Up ASLR, and High Entropy ASLR makes memory structures unpredictable, thwarting return-oriented programming (ROP) exploits. 3. <xhtml:strong>Control Flow Guard (CFG)</xhtml:strong>: Verifies control flow integrity for indirect call targets at compile time, preventing attackers from hijacking indirect jumps to point to arbitrary payloads. 4. <xhtml:strong>Structured Exception Handler Overwrite Protection (SEHOP)</xhtml:strong>: Blocks exploits that overwrite Structured Exception Handlers (SEH) to gain control of execution paths during error handling. 5. <xhtml:strong>Heap Termination on Corruption</xhtml:strong>: Immediately terminates a process if corruption is detected in its heap. This blocks heap-based buffer overflow exploitation before execution control can be seized.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Generate the Reference XML Configuration File</xhtml:h4>
        <xhtml:p>Before configuring the GPO, you must create a reference XML file containing the desired Exploit Protection mitigations: 1. On a reference workstation, open the <xhtml:strong>Windows Security</xhtml:strong> app. 2. Select <xhtml:strong>App &amp; browser control</xhtml:strong> and click <xhtml:strong>Exploit protection settings</xhtml:strong>. 3. Under the <xhtml:strong>System settings</xhtml:strong> tab, configure the following: <xhtml:em> </xhtml:em>
          <xhtml:em>Control Flow Guard (CFG)</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Data Execution Prevention (DEP)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>Force randomization for images (Mandatory ASLR)</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Randomize memory allocations (Bottom-up ASLR)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>High-entropy ASLR</xhtml:em>
          <xhtml:em>: On by default </xhtml:em>
          <xhtml:strong>Validate exception chains (SEHOP)</xhtml:strong>: On by default <xhtml:em> </xhtml:em>
          <xhtml:em>Validate heap integrity</xhtml:em>
          <xhtml:em>: On by default 4. Select the </xhtml:em>
          <xhtml:em>Program settings</xhtml:em>
          <xhtml:em> tab and configure application-specific overrides for Microsoft Office (`winword.exe`, `excel.exe`, etc.), Web Browsers, and PDF viewers to apply EAF, IAF, and ROP mitigations. 5. Scroll to the bottom of the page and click </xhtml:em>
          <xhtml:em>Export settings</xhtml:em>*. 6. Save the file as <xhtml:code>ExploitProtectionSettings.xml</xhtml:code>. 7. Copy this XML file to a location accessible by target endpoints, or distribute it to local target directories (e.g., <xhtml:code>C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml</xhtml:code>) via Group Policy Preferences (Files).</xhtml:p>
        <xhtml:h4>Step 2: Configure the Group Policy Setting</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management workstation.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\Windows Components\Windows Defender Exploit Guard\Exploit Protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Use a common set of exploit protection settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Options</xhtml:em>
            <xhtml:em>: Under the </xhtml:em>Path<xhtml:em> or </xhtml:em>Url* field, enter the full path to the XML file (e.g., <xhtml:code>C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml</xhtml:code> or a UNC share path).</xhtml:li>
          <xhtml:li>If utilizing Microsoft Security Guide templates:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\MS Security Guide</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Configure policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Enable Certificate Padding` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Enable Structured Exception Handling Overwrite Protection (SEHOP)` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Lock down Exploit Protection settings against user tampering:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Defender Security Center\App and Browser protection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Configure policy: </xhtml:em>
            <xhtml:em>Prevent users from modifying settings</xhtml:em>
            <xhtml:em> -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target client endpoints and member servers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the exploit protection profile locally on individual systems or standalone hosts.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-ExploitProtection.ps1">Download Script: Configure-ExploitProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-ExploitProtection.ps1
# Description: Generates the system-wide and application-specific Exploit Protection XML profile, applies it locally, and configures the policy registry keys.

Write-Host "Applying Exploit Protection Profile..." -ForegroundColor Cyan

# 1. Define the XML content including System and App settings
$XmlContent = @"
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;MitigationPolicy&gt;
  &lt;SystemConfig&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;SEHOP Enable="true" TelemetryOnly="false" /&gt;
    &lt;Heap TerminateOnError="true" /&gt;
  &lt;/SystemConfig&gt;
  &lt;AppConfig Executable="WINWORD.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="EXCEL.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="POWERPNT.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="OUTLOOK.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="MSACCESS.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="MSPUB.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="VISIO.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="LYNC.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="AcroRd32.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="Acrobat.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="chrome.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="msedge.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="firefox.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="wscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="cscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="powershell.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="java.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="javaw.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="javaws.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
&lt;/MitigationPolicy&gt;
"@

# 2. Create the target directory and write the XML file
$TargetDir = "C:\ProgramData\ExploitProtection"
if (-not (Test-Path $TargetDir)) {
    New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
}

$XmlPath = "$TargetDir\ExploitProtectionSettings.xml"
Set-Content -Path $XmlPath -Value $XmlContent -Encoding UTF8
Write-Host "Exploit Protection XML profile written to $($XmlPath)" -ForegroundColor Gray

# 3. Apply the settings locally using the cmdlet
if (Get-Command Set-ProcessMitigation -ErrorAction SilentlyContinue) {
    Set-ProcessMitigation -PolicyFilePath $XmlPath
    Write-Host "[+] Exploit protection system settings applied locally." -ForegroundColor Green
} else {
    Write-Warning "Set-ProcessMitigation cmdlet is not available. Please ensure you are running Windows 10/11 or Windows Server 2016+."
}

# 4. Configure policy registry keys to point to the XML file
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -Value $XmlPath -Type String -Force
Write-Host "[+] GPO policy registry values configured." -ForegroundColor Green

# 5. Configure MS Security Guide mitigations: Certificate Padding check and SEHOP registry keys
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustPath)) {
    New-Item -Path $WintrustPath -Force | Out-Null
}
Set-ItemProperty -Path $WintrustPath -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustWow64Path)) {
    New-Item -Path $WintrustWow64Path -Force | Out-Null
}
Set-ItemProperty -Path $WintrustWow64Path -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
if (-not (Test-Path $SessionKernelPath)) {
    New-Item -Path $SessionKernelPath -Force | Out-Null
}
Set-ItemProperty -Path $SessionKernelPath -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "[+] Certificate Padding check and SEHOP registry keys applied." -ForegroundColor Green

# 6. Prevent users from modifying Exploit Protection settings in Windows Security Center
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
if (-not (Test-Path $SecCenterPath)) {
    New-Item -Path $SecCenterPath -Force | Out-Null
}
Set-ItemProperty -Path $SecCenterPath -Name "DisallowExploitProtectionOverride" -Value 1 -Type DWord -Force
Write-Host "[+] Exploit protection override lockdown applied." -ForegroundColor Green

Write-Host "Exploit Protection Profile application completed successfully." -ForegroundColor Cyan</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-ExploitProtectionStatus.ps1">Download Script: Get-ExploitProtectionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-ExploitProtectionStatus.ps1
# Description: Audits the system-wide Exploit Protection settings against the recommended security baseline.

Write-Host "Auditing system-wide Exploit Protection mitigations..." -ForegroundColor Cyan

$BaselineFailed = $false
$Mitigations = Get-ProcessMitigation -System

# Helper function to evaluate and display status
function Test-MitigationSetting {
    param(
        [string]$MitigationName,
        [string]$CurrentValue,
        [string]$ExpectedValue
    )
    if ($CurrentValue -eq $ExpectedValue) {
        Write-Host "  [PASS] $($MitigationName): $($CurrentValue)" -ForegroundColor Green
    } else {
        Write-Host "  [FAIL] $($MitigationName): $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:BaselineFailed = $true
    }
}

Write-Host "`nSystem-wide Mitigations:" -ForegroundColor Gray

# Audit DEP
Test-MitigationSetting -MitigationName "DEP Enable" -CurrentValue $Mitigations.DEP.Enable -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "DEP EmulateAtlThunks" -CurrentValue $Mitigations.DEP.EmulateAtlThunks -ExpectedValue "OFF"

# Audit ASLR
Test-MitigationSetting -MitigationName "ASLR ForceRelocateImages" -CurrentValue $Mitigations.ASLR.ForceRelocateImages -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR BottomUp" -CurrentValue $Mitigations.ASLR.BottomUp -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR HighEntropy" -CurrentValue $Mitigations.ASLR.HighEntropy -ExpectedValue "ON"

# Audit CFG
Test-MitigationSetting -MitigationName "CFG Enable" -CurrentValue $Mitigations.CFG.Enable -ExpectedValue "ON"

# Audit SEHOP
Test-MitigationSetting -MitigationName "SEHOP Enable" -CurrentValue $Mitigations.SEHOP.Enable -ExpectedValue "ON"

# Audit Heap
Test-MitigationSetting -MitigationName "Heap TerminateOnError" -CurrentValue $Mitigations.Heap.TerminateOnError -ExpectedValue "ON"

# Audit Registry Policy and XML Configuration
Write-Host "`nRegistry Policy and XML Configuration:" -ForegroundColor Gray
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (Test-Path $RegPath) {
    $SettingsValue = Get-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -ErrorAction SilentlyContinue
    if ($SettingsValue -and $SettingsValue.ExploitProtectionSettings -ne "") {
        $XmlPath = $SettingsValue.ExploitProtectionSettings
        Write-Host "  [PASS] Exploit Protection Policy registry key is configured." -ForegroundColor Green
        Write-Host "         Path: $XmlPath" -ForegroundColor Gray
        
        if (Test-Path $XmlPath) {
            Write-Host "  [PASS] Exploit Protection XML file exists." -ForegroundColor Green
            try {
                [xml]$xml = Get-Content -Path $XmlPath -Raw -ErrorAction Stop
                
                # Verify SystemConfig block
                if ($xml.MitigationPolicy.SystemConfig) {
                    Write-Host "  [PASS] XML contains SystemConfig block." -ForegroundColor Green
                } else {
                    Write-Host "  [FAIL] XML is missing SystemConfig block." -ForegroundColor Red
                    $BaselineFailed = $true
                }
                
                # Verify major AppConfigs
                $ExpectedApps = @("WINWORD.EXE", "EXCEL.EXE", "chrome.exe", "msedge.exe", "AcroRd32.exe", "java.exe")
                $ConfiguredApps = $xml.MitigationPolicy.AppConfig | ForEach-Object { $_.Executable }
                
                foreach ($app in $ExpectedApps) {
                    if ($ConfiguredApps -contains $app) {
                        Write-Host "  [PASS] XML contains application profile for: $app" -ForegroundColor Green
                    } else {
                        Write-Host "  [FAIL] XML is missing application profile for: $app" -ForegroundColor Red
                        $BaselineFailed = $true
                    }
                }
            } catch {
                Write-Host "  [FAIL] Failed to parse Exploit Protection XML. Error: $($_.Exception.Message)" -ForegroundColor Red
                $BaselineFailed = $true
            }
        } else {
            Write-Host "  [FAIL] Exploit Protection XML file does not exist at specified path." -ForegroundColor Red
            $BaselineFailed = $true
        }
    } else {
        Write-Host "  [FAIL] Exploit Protection Policy registry key is empty or missing." -ForegroundColor Red
        $BaselineFailed = $true
    }
} else {
    Write-Host "  [FAIL] Exploit Protection Policy registry path does not exist." -ForegroundColor Red
    $BaselineFailed = $true
}

# Audit MS Security Guide Registry Settings
Write-Host "`nMS Security Guide Mitigations (Certificate Padding &amp; SEHOP):" -ForegroundColor Gray

function Test-MitigationRegistryValue ($path, $name, $expectedValue) {
    $val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    $color = "Red"
    if ($actual -eq $expectedValue) {
        $color = "Green"
    } else {
        $script:BaselineFailed = $true
    }
    Write-Host "    - Registry Setting: $name | Actual: '$actual' (Expected: '$expectedValue')" -ForegroundColor $color
}

$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustPath "EnableCertPaddingCheck" 1

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustWow64Path "EnableCertPaddingCheck" 1

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
Test-MitigationRegistryValue $SessionKernelPath "DisableExceptionChainValidation" 0

$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
Test-MitigationRegistryValue $SecCenterPath "DisallowExploitProtectionOverride" 1

Write-Host ""
if ($BaselineFailed) {
    Write-Host "Auditing FAILED: One or more configurations do not match the secure baseline." -ForegroundColor Red
    exit 1
} else {
    Write-Host "Auditing PASSED: All configurations match the secure baseline." -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-ExploitProtection.ps1
# Description: Generates the system-wide and application-specific Exploit Protection XML profile, applies it locally, and configures the policy registry keys.

Write-Host "Applying Exploit Protection Profile..." -ForegroundColor Cyan

# 1. Define the XML content including System and App settings
$XmlContent = @"
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;MitigationPolicy&gt;
  &lt;SystemConfig&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;SEHOP Enable="true" TelemetryOnly="false" /&gt;
    &lt;Heap TerminateOnError="true" /&gt;
  &lt;/SystemConfig&gt;
  &lt;AppConfig Executable="WINWORD.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="EXCEL.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="POWERPNT.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="OUTLOOK.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="MSACCESS.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="MSPUB.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="VISIO.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="LYNC.EXE"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="AcroRd32.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="Acrobat.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="chrome.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="msedge.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="firefox.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="wscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="cscript.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
    &lt;ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="powershell.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="java.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="javaw.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
  &lt;AppConfig Executable="javaws.exe"&gt;
    &lt;DEP Enable="true" EmulateAtlThunks="false" /&gt;
    &lt;ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" /&gt;
    &lt;ControlFlowGuard Enable="true" SuppressExports="false" /&gt;
    &lt;Payload EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" /&gt;
  &lt;/AppConfig&gt;
&lt;/MitigationPolicy&gt;
"@

# 2. Create the target directory and write the XML file
$TargetDir = "C:\ProgramData\ExploitProtection"
if (-not (Test-Path $TargetDir)) {
    New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
}

$XmlPath = "$TargetDir\ExploitProtectionSettings.xml"
Set-Content -Path $XmlPath -Value $XmlContent -Encoding UTF8
Write-Host "Exploit Protection XML profile written to $($XmlPath)" -ForegroundColor Gray

# 3. Apply the settings locally using the cmdlet
if (Get-Command Set-ProcessMitigation -ErrorAction SilentlyContinue) {
    Set-ProcessMitigation -PolicyFilePath $XmlPath
    Write-Host "[+] Exploit protection system settings applied locally." -ForegroundColor Green
} else {
    Write-Warning "Set-ProcessMitigation cmdlet is not available. Please ensure you are running Windows 10/11 or Windows Server 2016+."
}

# 4. Configure policy registry keys to point to the XML file
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -Value $XmlPath -Type String -Force
Write-Host "[+] GPO policy registry values configured." -ForegroundColor Green

# 5. Configure MS Security Guide mitigations: Certificate Padding check and SEHOP registry keys
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustPath)) {
    New-Item -Path $WintrustPath -Force | Out-Null
}
Set-ItemProperty -Path $WintrustPath -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustWow64Path)) {
    New-Item -Path $WintrustWow64Path -Force | Out-Null
}
Set-ItemProperty -Path $WintrustWow64Path -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force

$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
if (-not (Test-Path $SessionKernelPath)) {
    New-Item -Path $SessionKernelPath -Force | Out-Null
}
Set-ItemProperty -Path $SessionKernelPath -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "[+] Certificate Padding check and SEHOP registry keys applied." -ForegroundColor Green

# 6. Prevent users from modifying Exploit Protection settings in Windows Security Center
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
if (-not (Test-Path $SecCenterPath)) {
    New-Item -Path $SecCenterPath -Force | Out-Null
}
Set-ItemProperty -Path $SecCenterPath -Name "DisallowExploitProtectionOverride" -Value 1 -Type DWord -Force
Write-Host "[+] Exploit protection override lockdown applied." -ForegroundColor Green

Write-Host "Exploit Protection Profile application completed successfully." -ForegroundColor Cyan</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8020" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-021" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-021] Restrict Safe Mode Access to Administrators</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/disable-safe-mode-for-standard-users.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Malicious actors with standard user credentials can potentially bypass local security policies, local endpoint detection and response (EDR) agents, and group policy restrictions by booting the system into Safe Mode. In Safe Mode, many security agents and services do not load, creating an environment where local controls can be circumvented.</xhtml:p>
        <xhtml:p>By configuring <xhtml:code>SafeModeBlockNonAdmins = 1</xhtml:code>: 1. <xhtml:strong>Prevent Credential Bypass</xhtml:strong>: Standard users are blocked from logging in during Safe Mode, ensuring they cannot exploit the disabled security agents to execute unauthorized programs or extract system information. 2. <xhtml:strong>Maintenance Integrity</xhtml:strong>: Safe Mode remains accessible exclusively to system administrators for debugging and recovery, ensuring administrative capability is preserved while mitigating standard user risk.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>Because there is no native Administrative Template (ADMX) policy for this setting, it must be deployed using Group Policy Preferences (GPP) to configure the registry directly.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click in the right pane, select <xhtml:strong>New</xhtml:strong> &gt; <xhtml:strong>Registry Item</xhtml:strong>, and configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SafeModeBlockNonAdmins</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target client endpoints and member servers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone systems or during reference image build phases.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DisableSafeModeNonAdmins.ps1">Download Script: Configure-DisableSafeModeNonAdmins.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DisableSafeModeNonAdmins.ps1
# Description: Prevents standard users from logging into the system while in Safe Mode by setting SafeModeBlockNonAdmins to 1.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"
$ValueData = 1

Write-Host "Applying hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SafeModeNonAdminsStatus.ps1">Download Script: Get-SafeModeNonAdminsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SafeModeNonAdminsStatus.ps1
# Description: Checks the current configuration state of SafeModeBlockNonAdmins registry setting.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"

Write-Host "Auditing hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (Test-Path $RegPath) {
    $value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $value -and $value.$ValueName -eq 1) {
        Write-Host "Audit Result: Compliant. Standard users are blocked from logging in during Safe Mode ($ValueName = 1)." -ForegroundColor Green
        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. Standard users are allowed to log in during Safe Mode." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSafeModeNonAdmins.ps1
# Description: Prevents standard users from logging into the system while in Safe Mode by setting SafeModeBlockNonAdmins to 1.

$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "SafeModeBlockNonAdmins"
$ValueData = 1

Write-Host "Applying hardening requirement: Restrict Safe Mode access to administrators..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8021" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-022" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-022] Configure Windows Defender Firewall and Block LOLBins</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-windows-firewall.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Defender Firewall is the primary host-based security control protecting endpoints from unauthorized incoming network connections and regulating outgoing network behaviors. A secure baseline requires enabling the firewall on all profiles, setting inbound connections to block by default, disabling notification prompts that can be bypassed by users, and implementing detailed auditing/logging to monitor network anomalies.</xhtml:p>
        <xhtml:p>Additionally: 1. <xhtml:strong>Outbound LOLBins Blocking</xhtml:strong>: Malicious actors frequently abuse built-in Windows administrative utilities (known as Living Off the Land Binaries, or LOLBins) to download malicious payloads, exfiltrate sensitive data, and communicate with external command-and-control (C2) servers. Blocking outbound network communication for binaries that have no legitimate business requirement to connect to external networks (such as <xhtml:code>mshta.exe</xhtml:code>, <xhtml:code>certutil.exe</xhtml:code>, <xhtml:code>bitsadmin.exe</xhtml:code>, <xhtml:code>regsvr32.exe</xhtml:code>, <xhtml:code>rundll32.exe</xhtml:code>, <xhtml:code>cscript.exe</xhtml:code>, <xhtml:code>wscript.exe</xhtml:code>, and <xhtml:code>hh.exe</xhtml:code>) significantly mitigates these threat vectors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Configure Profile States and Logging</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management workstation.</xhtml:li>
          <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Windows Defender Firewall with Advanced Security</xhtml:strong> and select <xhtml:strong>Properties</xhtml:strong>.</xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Domain Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\domainfw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Private Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\privatefw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the <xhtml:strong>Public Profile</xhtml:strong> tab:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Firewall state</xhtml:em>*: <xhtml:code>On (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Inbound connections</xhtml:em>*: <xhtml:code>Block (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Outbound connections</xhtml:em>*: <xhtml:code>Allow (default)</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Settings</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Display a notification</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local firewall rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Apply local connection security rules</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Click </xhtml:em>
            <xhtml:em>Customize...</xhtml:em>
            <xhtml:em> under </xhtml:em>
            <xhtml:em>Logging</xhtml:em>*:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\logfiles\firewall\publicfw.log</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Size limit (KB)</xhtml:em>*: <xhtml:code>16384</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log dropped packets</xhtml:em>*: <xhtml:code>Yes</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Log successful connections</xhtml:em>*: <xhtml:code>No</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Create Outbound Rules for Known LOLBins</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security\Outbound Rules</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new rule for each target LOLBin binary (e.g., mshta.exe, certutil.exe, bitsadmin.exe, regsvr32.exe, rundll32.exe, cscript.exe, wscript.exe, hh.exe, calc.exe, notepad.exe, conhost.exe, RunScriptHelper.exe):</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>Outbound Rules</xhtml:em>
            <xhtml:em> and select </xhtml:em>
            <xhtml:em>New Rule...</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Rule Type</xhtml:em>*: <xhtml:code>Program</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Program</xhtml:em>*: Choose <xhtml:code>This program path</xhtml:code> and enter the path matching the binary (both x64 and x86 paths if applicable, e.g., <xhtml:code>%SystemRoot%\System32\mshta.exe</xhtml:code> and <xhtml:code>%SystemRoot%\SysWOW64\mshta.exe</xhtml:code>).</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Block the connection</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Profile</xhtml:em>*: Select <xhtml:code>Domain</xhtml:code>, <xhtml:code>Private</xhtml:code>, and <xhtml:code>Public</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Name</xhtml:em>*: Specify a descriptive name (e.g., <xhtml:code>Hardening: Block Outbound mshta.exe (x64)</xhtml:code>).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to configure Windows Defender Firewall profiles, logging parameters, merge settings, and outbound LOLBins rules.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-WindowsFirewall.ps1">Download Script: Configure-WindowsFirewall.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-WindowsFirewall.ps1
# Description: Configures Windows Defender Firewall profiles (Domain, Private, Public) and blocks outbound traffic for known LOLBins.

Write-Host "Configuring Windows Defender Firewall profiles..." -ForegroundColor Cyan

# 1. Configure profiles
$FWProfiles = @("Domain", "Private", "Public")
foreach ($FWProfile in $FWProfiles) {
    $LogFile = "$env:windir\System32\logfiles\firewall\$($FWProfile.ToLower())fw.log"
    
    Set-NetFirewallProfile -Profile $FWProfile `
        -Enabled True `
        -DefaultInboundAction Block `
        -DefaultOutboundAction Allow `
        -NotifyOnListen False `
        -AllowLocalPolicyMerge False `
        -AllowLocalIPsecPolicyMerge False `
        -LogFileName $LogFile `
        -LogMaxSizeKilobytes 16384 `
        -LogBlocked True `
        -LogAllowed False | Out-Null
    Write-Host "[+] Profile '$FWProfile' configured with logging and defaults." -ForegroundColor Green
}

# 2. Block outbound traffic for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Configuring outbound firewall block rules for known LOLBins..." -ForegroundColor Cyan

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Existing = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -DisplayName $DisplayName `
            -Name $DisplayName `
            -Direction Outbound `
            -Action Block `
            -Program $Bin.Path `
            -Profile Any `
            -Enabled True | Out-Null
        Write-Host "[+] Outbound block rule created for $($Bin.Name)." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -DisplayName $DisplayName -Action Block -Enabled True | Out-Null
        Write-Host "[~] Outbound block rule for $($Bin.Name) already exists, updated state to Enabled/Block." -ForegroundColor Gray
    }
}

Write-Host "Firewall profiles and LOLBins outbound rules configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the settings have been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-WindowsFirewallStatus.ps1">Download Script: Get-WindowsFirewallStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WindowsFirewallStatus.ps1
# Description: Audits Windows Defender Firewall profile configurations and outbound block rules for known LOLBins.

Write-Host "--- Auditing Windows Defender Firewall Configuration ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper function to audit firewall profiles
function Test-FirewallProfile ($ProfileName, $ExpectMergeLocal, $ExpectMergeIPsec) {
    $FWProfile = Get-NetFirewallProfile -Profile $ProfileName -ErrorAction SilentlyContinue
    if ($null -eq $FWProfile) {
        Write-Host "    - Profile '$ProfileName' NOT FOUND" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    
    $EnabledColor = if ($FWProfile.Enabled -eq $true) { "Green" } else { "Red" }
    $InboundColor = if ($FWProfile.DefaultInboundAction -eq "Block") { "Green" } else { "Red" }
    $OutboundColor = if ($FWProfile.DefaultOutboundAction -eq "Allow") { "Green" } else { "Red" }
    $NotifyColor = if ($FWProfile.NotifyOnListen -eq $false) { "Green" } else { "Red" }
    
    Write-Host "  * Profile: $ProfileName" -ForegroundColor Gray
    Write-Host "    - Enabled: $($FWProfile.Enabled) (Expected: True)" -ForegroundColor $EnabledColor
    Write-Host "    - DefaultInboundAction: $($FWProfile.DefaultInboundAction) (Expected: Block)" -ForegroundColor $InboundColor
    Write-Host "    - DefaultOutboundAction: $($FWProfile.DefaultOutboundAction) (Expected: Allow)" -ForegroundColor $OutboundColor
    Write-Host "    - NotifyOnListen: $($FWProfile.NotifyOnListen) (Expected: False)" -ForegroundColor $NotifyColor
    
    # Check log configurations
    $LogPath = "$env:windir\System32\logfiles\firewall\$($ProfileName.ToLower())fw.log"
    $LogPathColor = if ($FWProfile.LogFileName -eq $LogPath) { "Green" } else { "Red" }
    $LogSizeColor = if ($FWProfile.LogMaxSizeKilobytes -ge 16384) { "Green" } else { "Red" }
    $LogBlockedColor = if ($FWProfile.LogBlocked -eq $true) { "Green" } else { "Red" }
    $LogAllowedColor = if ($FWProfile.LogAllowed -eq $false) { "Green" } else { "Red" }
    
    Write-Host "    - LogFileName: $($FWProfile.LogFileName) (Expected: $LogPath)" -ForegroundColor $LogPathColor
    Write-Host "    - LogMaxSizeKilobytes: $($FWProfile.LogMaxSizeKilobytes) (Expected: &gt;= 16384)" -ForegroundColor $LogSizeColor
    Write-Host "    - LogBlocked: $($FWProfile.LogBlocked) (Expected: True)" -ForegroundColor $LogBlockedColor
    Write-Host "    - LogAllowed: $($FWProfile.LogAllowed) (Expected: False)" -ForegroundColor $LogAllowedColor
    
    if ($FWProfile.Enabled -ne $true -or $FWProfile.DefaultInboundAction -ne "Block" -or $FWProfile.NotifyOnListen -ne $false -or $FWProfile.LogFileName -ne $LogPath -or $FWProfile.LogMaxSizeKilobytes -lt 16384 -or $FWProfile.LogBlocked -ne $true -or $FWProfile.LogAllowed -ne $false) {
        $script:Vulnerable = $true
    }
    
    if ($null -ne $ExpectMergeLocal) {
        $MergeLocalColor = if ($FWProfile.AllowLocalPolicyMerge -eq $ExpectMergeLocal) { "Green" } else { "Red" }
        Write-Host "    - AllowLocalPolicyMerge: $($FWProfile.AllowLocalPolicyMerge) (Expected: $ExpectMergeLocal)" -ForegroundColor $MergeLocalColor
        if ($FWProfile.AllowLocalPolicyMerge -ne $ExpectMergeLocal) { $script:Vulnerable = $true }
    }
    if ($null -ne $ExpectMergeIPsec) {
        $MergeIPsecColor = if ($FWProfile.AllowLocalIPsecPolicyMerge -eq $ExpectMergeIPsec) { "Green" } else { "Red" }
        Write-Host "    - AllowLocalIPsecPolicyMerge: $($FWProfile.AllowLocalIPsecPolicyMerge) (Expected: $ExpectMergeIPsec)" -ForegroundColor $MergeIPsecColor
        if ($FWProfile.AllowLocalIPsecPolicyMerge -ne $ExpectMergeIPsec) { $script:Vulnerable = $true }
    }
}

Write-Host "Auditing profiles..." -ForegroundColor Gray
Test-FirewallProfile -ProfileName "Domain" -ExpectMergeLocal $false -ExpectMergeIPsec $false
Test-FirewallProfile -ProfileName "Private" -ExpectMergeLocal $false -ExpectMergeIPsec $false
Test-FirewallProfile -ProfileName "Public" -ExpectMergeLocal $false -ExpectMergeIPsec $false

# Audit outbound rules for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Auditing outbound firewall rules for known LOLBins..." -ForegroundColor Gray

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Rule = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    $Color = "Red"
    
    if ($null -ne $Rule) {
        $ProgFilter = Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $Rule -ErrorAction SilentlyContinue
        $ProgPath = "None"
        if ($null -ne $ProgFilter) {
            $ProgPath = $ProgFilter.Program
        }
        
        if ($Rule.Enabled -eq $true -and $Rule.Direction -eq "Outbound" -and $Rule.Action -eq "Block" -and $ProgPath -eq $Bin.Path) {
            $Color = "Green"
            Write-Host "    - Firewall Rule: $DisplayName | Enabled: True | Action: Block | Program: $ProgPath (Compliant)" -ForegroundColor $Color
        } else {
            $script:Vulnerable = $true
            Write-Host "    - Firewall Rule: $DisplayName | Enabled: $($Rule.Enabled) | Action: $($Rule.Action) | Program: $ProgPath (Non-Compliant)" -ForegroundColor $Color
        }
    } else {
        $script:Vulnerable = $true
        Write-Host "    - Firewall Rule: $DisplayName | NOT FOUND (Non-Compliant)" -ForegroundColor $Color
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-WindowsFirewall.ps1
# Description: Configures Windows Defender Firewall profiles (Domain, Private, Public) and blocks outbound traffic for known LOLBins.

Write-Host "Configuring Windows Defender Firewall profiles..." -ForegroundColor Cyan

# 1. Configure profiles
$FWProfiles = @("Domain", "Private", "Public")
foreach ($FWProfile in $FWProfiles) {
    $LogFile = "$env:windir\System32\logfiles\firewall\$($FWProfile.ToLower())fw.log"
    
    Set-NetFirewallProfile -Profile $FWProfile `
        -Enabled True `
        -DefaultInboundAction Block `
        -DefaultOutboundAction Allow `
        -NotifyOnListen False `
        -AllowLocalPolicyMerge False `
        -AllowLocalIPsecPolicyMerge False `
        -LogFileName $LogFile `
        -LogMaxSizeKilobytes 16384 `
        -LogBlocked True `
        -LogAllowed False | Out-Null
    Write-Host "[+] Profile '$FWProfile' configured with logging and defaults." -ForegroundColor Green
}

# 2. Block outbound traffic for known LOLBins
$Lolbins = @(
    @{ Name = "mshta.exe (x64)"; Path = "%SystemRoot%\System32\mshta.exe" },
    @{ Name = "mshta.exe (x86)"; Path = "%SystemRoot%\SysWOW64\mshta.exe" },
    @{ Name = "certutil.exe (x64)"; Path = "%SystemRoot%\System32\certutil.exe" },
    @{ Name = "certutil.exe (x86)"; Path = "%SystemRoot%\SysWOW64\certutil.exe" },
    @{ Name = "bitsadmin.exe (x64)"; Path = "%SystemRoot%\System32\bitsadmin.exe" },
    @{ Name = "bitsadmin.exe (x86)"; Path = "%SystemRoot%\SysWOW64\bitsadmin.exe" },
    @{ Name = "regsvr32.exe (x64)"; Path = "%SystemRoot%\System32\regsvr32.exe" },
    @{ Name = "regsvr32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\regsvr32.exe" },
    @{ Name = "rundll32.exe (x64)"; Path = "%SystemRoot%\System32\rundll32.exe" },
    @{ Name = "rundll32.exe (x86)"; Path = "%SystemRoot%\SysWOW64\rundll32.exe" },
    @{ Name = "cscript.exe (x64)"; Path = "%SystemRoot%\System32\cscript.exe" },
    @{ Name = "cscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\cscript.exe" },
    @{ Name = "wscript.exe (x64)"; Path = "%SystemRoot%\System32\wscript.exe" },
    @{ Name = "wscript.exe (x86)"; Path = "%SystemRoot%\SysWOW64\wscript.exe" },
    @{ Name = "hh.exe (x64)"; Path = "%SystemRoot%\hh.exe" },
    @{ Name = "hh.exe (x86)"; Path = "%SystemRoot%\SysWOW64\hh.exe" },
    @{ Name = "calc.exe (x64)"; Path = "%SystemRoot%\System32\calc.exe" },
    @{ Name = "calc.exe (x86)"; Path = "%SystemRoot%\SysWOW64\calc.exe" },
    @{ Name = "notepad.exe (x64)"; Path = "%SystemRoot%\System32\notepad.exe" },
    @{ Name = "notepad.exe (x86)"; Path = "%SystemRoot%\SysWOW64\notepad.exe" },
    @{ Name = "conhost.exe (x64)"; Path = "%SystemRoot%\System32\conhost.exe" },
    @{ Name = "conhost.exe (x86)"; Path = "%SystemRoot%\SysWOW64\conhost.exe" },
    @{ Name = "RunScriptHelper.exe (x64)"; Path = "%SystemRoot%\System32\RunScriptHelper.exe" },
    @{ Name = "RunScriptHelper.exe (x86)"; Path = "%SystemRoot%\SysWOW64\RunScriptHelper.exe" }
)

Write-Host "Configuring outbound firewall block rules for known LOLBins..." -ForegroundColor Cyan

foreach ($Bin in $Lolbins) {
    $DisplayName = "Hardening: Block Outbound $($Bin.Name)"
    $Existing = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue
    if ($null -eq $Existing) {
        New-NetFirewallRule -DisplayName $DisplayName `
            -Name $DisplayName `
            -Direction Outbound `
            -Action Block `
            -Program $Bin.Path `
            -Profile Any `
            -Enabled True | Out-Null
        Write-Host "[+] Outbound block rule created for $($Bin.Name)." -ForegroundColor Green
    } else {
        Set-NetFirewallRule -DisplayName $DisplayName -Action Block -Enabled True | Out-Null
        Write-Host "[~] Outbound block rule for $($Bin.Name) already exists, updated state to Enabled/Block." -ForegroundColor Gray
    }
}

Write-Host "Firewall profiles and LOLBins outbound rules configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8022" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-023" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-023] Enable LSA Protection with UEFI Lock</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1607+) and Windows 11 Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-lsa-protection.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (LSASS) process manages security policies, user authentication, and credential tokens on Windows systems. Attackers targeting workstations commonly attempt to extract plain-text credentials or NT hashes from LSASS memory using debugging tools (e.g., Mimikatz, Procdump).</xhtml:p>
        <xhtml:p>Enabling LSA Protection ensures that: 1. <xhtml:strong>Protected Process Light (PPL)</xhtml:strong>: The LSASS process runs as a Protected Process Light (PPL). 2. <xhtml:strong>Access Restriction</xhtml:strong>: Only verified, digitally signed code can load into LSASS, and standard processes (even those running as local system/administrator) cannot read the memory space of LSASS or inject code into it. 3. <xhtml:strong>Mitigating Dump Attacks</xhtml:strong>: Credential harvesting tools cannot dump LSASS memory to disk or scrape keys from LSA memory blocks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO linked to the workstations Organizational Unit (OU) (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Local Security Authority</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Configures LSASS to run as a protected process</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure LSA to run as a protected process</xhtml:em>*: <xhtml:code>Enabled with UEFI Lock</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the target workstations Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry key on the workstation to run LSASS as a protected process with UEFI Lock.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-LsaProtection.ps1">Download Script: Configure-LsaProtection.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-LsaProtection.ps1
# Description: Configures the RunAsPPL registry key to enable LSA Protection on workstations.

Write-Host "Applying LSA Protection registry hardening..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "[+] LSA Protection (RunAsPPL) enabled in registry. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the local LSA Protection state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-LsaProtectionStatus.ps1">Download Script: Get-LsaProtectionStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-LsaProtectionStatus.ps1
# Description: Checks the registry settings and running process state to verify LSA Protection is active.

Write-Host "--- Auditing LSA Protection Status ---" -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$RunAsPPL = (Get-ItemProperty -Path $LsaPath -Name "RunAsPPL" -ErrorAction SilentlyContinue).RunAsPPL

if ($RunAsPPL -eq 1) {
    Write-Host "    - LSA Protection (RunAsPPL): Enabled (Secure)" -ForegroundColor Green
} else {
    Write-Host "    - VULNERABLE: LSA Protection (RunAsPPL) is not configured or disabled (Value: $($RunAsPPL))" -ForegroundColor Red
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-LsaProtection.ps1
# Description: Configures the RunAsPPL registry key to enable LSA Protection on workstations.

Write-Host "Applying LSA Protection registry hardening..." -ForegroundColor Cyan

$LsaPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "RunAsPPL" -Value 1 -Type DWord
Write-Host "[+] LSA Protection (RunAsPPL) enabled in registry. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8023" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-025" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-025] Configure Secure Printing and Print Spooler Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-printing-and-spooler.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Print Spooler service (<xhtml:code>Spooler</xhtml:code>) has been the source of numerous high-severity vulnerabilities (such as the PrintNightmare family - CVE-2021-1675 and CVE-2021-34527). Attackers exploit the Print Spooler to coerce authentication or execute arbitrary code with SYSTEM privileges.</xhtml:p>
        <xhtml:p>To secure standard client endpoints and member servers, the primary defense is to <xhtml:strong>completely disable the Print Spooler service</xhtml:strong>. This eliminates the service's attack surface. As a secondary defense-in-depth, additional printer registry configurations (such as restricting driver installation to administrators, Redirection Guard, and RPC connection configurations) are enforced to ensure that even if the spooler service is temporarily running, the subsystem remains hardened.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Remote Connections Block</xhtml:strong>: By disabling remote client connections to the print spooler, standard client endpoints are prevented from acting as print servers. Outbound printing remains unaffected, but external hosts can no longer target the workstation's print spooler over the network.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Redirection Guard</xhtml:strong>: Enabling Redirection Guard prevents print spooler processing from being redirected via symbolic links or junction points, mitigating local privilege escalation vectors that abuse file system paths during printer driver mapping.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>RPC over TCP</xhtml:strong>: Forcing both incoming and outgoing RPC connections to use TCP instead of legacy Named Pipes (which can be easily hijacked or relayed) reduces the attack surface. Forcing packet-level privacy and authentication protocols ensures printing traffic is encrypted and authenticated.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Point and Print Restrictions</xhtml:strong>: Restricting driver installation and update prompts to administrators prevents non-privileged users from installing malicious or unverified printer drivers.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>1. Disable the Print Spooler Service</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO applied to client endpoints (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Print Spooler</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and select <xhtml:strong>Disabled</xhtml:strong>. Click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>2. Configure Printers GPO Hardening (Secondary Defense)</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Printers</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Print Spooler to accept client connections</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure Redirection Guard</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>, select <xhtml:code>Redirection Guard Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure RPC connection settings</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Protocol to use for outgoing RPC connections: <xhtml:code>RPC over TCP</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Use authentication for outgoing RPC connections: <xhtml:code>Default</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure RPC listener settings</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Protocols to allow for incoming RPC connections: <xhtml:code>RPC over TCP</xhtml:code>
          </xhtml:li>
          <xhtml:li>* Authentication protocol to use for incoming RPC connections: <xhtml:code>Negotiate</xhtml:code> (or higher)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure RPC over TCP port</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>, set Port to <xhtml:code>0</xhtml:code> (dynamic port allocation)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Configure RPC packet level privacy setting for incoming connections</xhtml:em>
            <xhtml:em>: Set to `Enabled` </xhtml:em>(Note: Requires <xhtml:code>SecGuide.admx</xhtml:code> template)*</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Manage processing of Queue-specific files</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>, select <xhtml:code>Limit Queue-specific files to Color profiles</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Point and Print Restrictions</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>* When installing drivers for a new connection: <xhtml:code>Show warning and elevation prompt</xhtml:code>
          </xhtml:li>
          <xhtml:li>* When updating drivers for an existing connection: <xhtml:code>Show warning and elevation prompt</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Limits print driver installation to Administrators</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure registry keys for print spooler hardening.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-PrintingAndSpooler.ps1">Download Script: Configure-PrintingAndSpooler.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-PrintingAndSpooler.ps1
# Description: Disables the Print Spooler service and configures secondary print registry hardening parameters on standard endpoints.

Write-Host "Applying Print Spooler security hardening..." -ForegroundColor Cyan

# 1. Disable the Print Spooler Service
if (Get-Service -Name "Spooler" -ErrorAction SilentlyContinue) {
    Set-Service -Name "Spooler" -StartupType Disabled -Confirm:$false
    Stop-Service -Name "Spooler" -Force -Confirm:$false
    Write-Host "[+] Print Spooler service has been stopped and disabled." -ForegroundColor Green
}

# 1. Base Printers Path Policies
$PrintersPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
if (-not (Test-Path $PrintersPath)) {
    New-Item -Path $PrintersPath -Force | Out-Null
}

# Allow Print Spooler to accept client connections -&gt; Disabled
Set-ItemProperty -Path $PrintersPath -Name "RegisterSpoolerRemoteRpcEndPoint" -Value 2 -Type Dword
Set-ItemProperty -Path $PrintersPath -Name "RegisterSpoolerRemoteSubsystem" -Value 0 -Type Dword

# Configure Redirection Guard -&gt; Enabled: Redirection Guard Enabled
Set-ItemProperty -Path $PrintersPath -Name "RedirectionguardPolicy" -Value 1 -Type Dword

# Manage processing of Queue-specific files -&gt; Enabled: Limit Queue-specific files to Color profiles
Set-ItemProperty -Path $PrintersPath -Name "CopyFilesPolicy" -Value 1 -Type Dword

# 2. Printers RPC Connection and Listener Policies
$PrintersRpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC"
if (-not (Test-Path $PrintersRpcPath)) {
    New-Item -Path $PrintersRpcPath -Force | Out-Null
}

# Protocol to use for outgoing RPC connections -&gt; RPC over TCP (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcUseNamedPipeProtocol" -Value 0 -Type Dword

# Use authentication for outgoing RPC connections -&gt; Default (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcAuthentication" -Value 0 -Type Dword

# Protocols to allow for incoming RPC connections -&gt; RPC over TCP (5)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcProtocols" -Value 5 -Type Dword

# Authentication protocol to use for incoming RPC connections -&gt; Negotiate (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "ForceKerberosForRpc" -Value 0 -Type Dword

# Configure RPC over TCP port -&gt; 0
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcTcpPort" -Value 0 -Type Dword

# 3. System Print Control Privacy Setting
$PrintControlPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Print"
if (-not (Test-Path $PrintControlPath)) {
    New-Item -Path $PrintControlPath -Force | Out-Null
}

# Configure RPC packet level privacy setting for incoming connections -&gt; Enabled
Set-ItemProperty -Path $PrintControlPath -Name "RpcAuthnLevelPrivacyEnabled" -Value 1 -Type Dword

# 4. Point and Print Restrictions
$PointPrintPath = "HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
if (-not (Test-Path $PointPrintPath)) {
    New-Item -Path $PointPrintPath -Force | Out-Null
}

Set-ItemProperty -Path $PointPrintPath -Name "RestrictPointAndPrint" -Value 1 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "NoWarningNoElevationOnInstall" -Value 0 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "UpdatePromptSettings" -Value 0 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "RestrictDriverInstallationToAdministrators" -Value 1 -Type Dword

Write-Host "[+] Print Spooler and Printer configurations hardened successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the print spooler policy settings:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-PrintingAndSpoolerStatus.ps1">Download Script: Get-PrintingAndSpoolerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-PrintingAndSpoolerStatus.ps1
# Description: Audits print spooler and printer security configurations on the local system.

Write-Host "--- Auditing Printing and Spooler Hardening ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# 1. Audit Spooler Service Startup Type
$Service = Get-Service -Name "Spooler" -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    $StartupType = (Get-CimInstance -ClassName Win32_Service -Filter "Name='Spooler'").StartMode
    $Color = if ($StartupType -eq "Disabled") { "Green" } else { "Red" }
    Write-Host "  [-] Print Spooler Service Startup: $StartupType (Expected: Disabled)" -ForegroundColor $Color
    if ($StartupType -ne "Disabled") {
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [+] Print Spooler Service is not present on this machine." -ForegroundColor Green
}

# Helper function to audit registry properties
function Test-RegistryValue {
    param(
        [string]$Path,
        [string]$Name,
        [object]$ExpectedValue
    )
    if (Test-Path $Path) {
        $Val = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
        if ($null -ne $Val) {
            $Actual = $Val.$Name
            if ($Actual -eq $ExpectedValue) {
                Write-Host "  - Path: $Path | Value: $Name | Current: $Actual (Expected: $ExpectedValue)" -ForegroundColor Green
            } else {
                Write-Host "  [!] MISMATCH: Path: $Path | Value: $Name | Current: $Actual (Expected: $ExpectedValue)" -ForegroundColor Red
                $script:Vulnerable = $true
            }
        } else {
            Write-Host "  [!] MISSING VALUE: Path: $Path | Value: $Name (Expected: $ExpectedValue)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING KEY: Path: $Path (Expected: $Name = $ExpectedValue)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# Audit base printer settings
$PrintersPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
Test-RegistryValue -Path $PrintersPath -Name "RegisterSpoolerRemoteRpcEndPoint" -ExpectedValue 2
Test-RegistryValue -Path $PrintersPath -Name "RegisterSpoolerRemoteSubsystem" -ExpectedValue 0
Test-RegistryValue -Path $PrintersPath -Name "RedirectionguardPolicy" -ExpectedValue 1
Test-RegistryValue -Path $PrintersPath -Name "CopyFilesPolicy" -ExpectedValue 1

# Audit RPC settings
$PrintersRpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC"
Test-RegistryValue -Path $PrintersRpcPath -Name "RpcUseNamedPipeProtocol" -ExpectedValue 0
Test-RegistryValue -Path $PrintersRpcPath -Name "RpcAuthentication" -ExpectedValue 0
Test-RegistryValue -Path $PrintersRpcPath -Name "RpcProtocols" -ExpectedValue 5
Test-RegistryValue -Path $PrintersRpcPath -Name "ForceKerberosForRpc" -ExpectedValue 0
Test-RegistryValue -Path $PrintersRpcPath -Name "RpcTcpPort" -ExpectedValue 0

# Audit Print Control
$PrintControlPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Print"
Test-RegistryValue -Path $PrintControlPath -Name "RpcAuthnLevelPrivacyEnabled" -ExpectedValue 1

# Audit Point and Print
$PointPrintPath = "HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
Test-RegistryValue -Path $PointPrintPath -Name "RestrictPointAndPrint" -ExpectedValue 1
Test-RegistryValue -Path $PointPrintPath -Name "NoWarningNoElevationOnInstall" -ExpectedValue 0
Test-RegistryValue -Path $PointPrintPath -Name "UpdatePromptSettings" -ExpectedValue 0
Test-RegistryValue -Path $PointPrintPath -Name "RestrictDriverInstallationToAdministrators" -ExpectedValue 1

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-PrintingAndSpooler.ps1
# Description: Disables the Print Spooler service and configures secondary print registry hardening parameters on standard endpoints.

Write-Host "Applying Print Spooler security hardening..." -ForegroundColor Cyan

# 1. Disable the Print Spooler Service
if (Get-Service -Name "Spooler" -ErrorAction SilentlyContinue) {
    Set-Service -Name "Spooler" -StartupType Disabled -Confirm:$false
    Stop-Service -Name "Spooler" -Force -Confirm:$false
    Write-Host "[+] Print Spooler service has been stopped and disabled." -ForegroundColor Green
}

# 1. Base Printers Path Policies
$PrintersPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
if (-not (Test-Path $PrintersPath)) {
    New-Item -Path $PrintersPath -Force | Out-Null
}

# Allow Print Spooler to accept client connections -&gt; Disabled
Set-ItemProperty -Path $PrintersPath -Name "RegisterSpoolerRemoteRpcEndPoint" -Value 2 -Type Dword
Set-ItemProperty -Path $PrintersPath -Name "RegisterSpoolerRemoteSubsystem" -Value 0 -Type Dword

# Configure Redirection Guard -&gt; Enabled: Redirection Guard Enabled
Set-ItemProperty -Path $PrintersPath -Name "RedirectionguardPolicy" -Value 1 -Type Dword

# Manage processing of Queue-specific files -&gt; Enabled: Limit Queue-specific files to Color profiles
Set-ItemProperty -Path $PrintersPath -Name "CopyFilesPolicy" -Value 1 -Type Dword

# 2. Printers RPC Connection and Listener Policies
$PrintersRpcPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC"
if (-not (Test-Path $PrintersRpcPath)) {
    New-Item -Path $PrintersRpcPath -Force | Out-Null
}

# Protocol to use for outgoing RPC connections -&gt; RPC over TCP (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcUseNamedPipeProtocol" -Value 0 -Type Dword

# Use authentication for outgoing RPC connections -&gt; Default (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcAuthentication" -Value 0 -Type Dword

# Protocols to allow for incoming RPC connections -&gt; RPC over TCP (5)
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcProtocols" -Value 5 -Type Dword

# Authentication protocol to use for incoming RPC connections -&gt; Negotiate (0)
Set-ItemProperty -Path $PrintersRpcPath -Name "ForceKerberosForRpc" -Value 0 -Type Dword

# Configure RPC over TCP port -&gt; 0
Set-ItemProperty -Path $PrintersRpcPath -Name "RpcTcpPort" -Value 0 -Type Dword

# 3. System Print Control Privacy Setting
$PrintControlPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Print"
if (-not (Test-Path $PrintControlPath)) {
    New-Item -Path $PrintControlPath -Force | Out-Null
}

# Configure RPC packet level privacy setting for incoming connections -&gt; Enabled
Set-ItemProperty -Path $PrintControlPath -Name "RpcAuthnLevelPrivacyEnabled" -Value 1 -Type Dword

# 4. Point and Print Restrictions
$PointPrintPath = "HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint"
if (-not (Test-Path $PointPrintPath)) {
    New-Item -Path $PointPrintPath -Force | Out-Null
}

Set-ItemProperty -Path $PointPrintPath -Name "RestrictPointAndPrint" -Value 1 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "NoWarningNoElevationOnInstall" -Value 0 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "UpdatePromptSettings" -Value 0 -Type Dword
Set-ItemProperty -Path $PointPrintPath -Name "RestrictDriverInstallationToAdministrators" -Value 1 -Type Dword

Write-Host "[+] Print Spooler and Printer configurations hardened successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8025" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-027" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-027] Configure AppLocker Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (and above), Windows 11 Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-applocker-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Endpoints and general member servers are the most common entry points for malware, ransomware, and administrative account compromise. Standard users running with non-administrative accounts can download and execute malicious executables or scripts in writeable directories (like <xhtml:code>%TEMP%</xhtml:code> or <xhtml:code>%USERPROFILE%</xhtml:code>) to bypass traditional signature-based antivirus solutions.</xhtml:p>
        <xhtml:p>Enforcing strict application control via AppLocker on endpoints ensures that: 1. <xhtml:strong>Malware Prevention</xhtml:strong>: Standard users are blocked from executing unauthorized binaries and installers. 2. <xhtml:strong>Defends Against AppLocker Bypasses</xhtml:strong>: Abusing trusted, signed Microsoft binaries (such as <xhtml:code>msbuild.exe</xhtml:code>, <xhtml:code>installutil.exe</xhtml:code>, <xhtml:code>regasm.exe</xhtml:code>, <xhtml:code>regsvcs.exe</xhtml:code>, <xhtml:code>mshta.exe</xhtml:code>, <xhtml:code>regsvr32.exe</xhtml:code>, <xhtml:code>rundll32.exe</xhtml:code>) allows attackers to execute arbitrary code bypassing default AppLocker rules. This control blocks these "Living off the Land" binaries (LOLBins) and prevents execution from user-writeable paths under <xhtml:code>%WINDIR%</xhtml:code> (such as <xhtml:code>Tasks</xhtml:code>, <xhtml:code>Temp</xhtml:code>, <xhtml:code>tracing</xhtml:code>, <xhtml:code>spool\drivers\color</xhtml:code>, etc.). 3. <xhtml:strong>Restricts Interpreted Codes</xhtml:strong>: Block unauthorized execution of scripts (PowerShell, VBScript, Batch) from writeable locations. 4. <xhtml:strong>Defense-in-Depth</xhtml:strong>: Limits the lateral movement of adversaries who pivot from one compromised endpoint to another.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit the GPO linked to the workstations/member servers Organizational Unit (OU) (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Application Identity</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Define this policy setting</xhtml:strong> and configure the startup mode to <xhtml:strong>Automatic</xhtml:strong>.</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Application Control Policies\AppLocker</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure AppLocker Enforcement:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click </xhtml:em>
            <xhtml:em>AppLocker</xhtml:em>
            <xhtml:em> and select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> On the </xhtml:em>
            <xhtml:em>Enforcement</xhtml:em>
            <xhtml:em> tab, check </xhtml:em>
            <xhtml:em>Configured</xhtml:em>* under:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Executable rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em> (or </xhtml:em>
            <xhtml:em>Audit only</xhtml:em>* for testing)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Windows Installer rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Script rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Packaged app rules</xhtml:em>
            <xhtml:em> -&gt; Select </xhtml:em>
            <xhtml:em>Enforce rules</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Executable Rules</xhtml:strong> and select <xhtml:strong>Create Default Rules</xhtml:strong> (this permits Windows files and program files).</xhtml:li>
          <xhtml:li>Delete the default rule allowing "Everyone" to run files in all locations, and replace it with a rule allowing only authorized administrative groups (e.g., <xhtml:code>Domain Admins</xhtml:code>, <xhtml:code>Local Administrators</xhtml:code>) to run binaries outside the default system locations.</xhtml:li>
          <xhtml:li>Per <xhtml:strong>ANSSI R2</xhtml:strong> recommendation, do not create standalone Deny rules. Instead, configure the following path <xhtml:strong>Exceptions</xhtml:strong> on the default Allow rule for the Windows folder:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Right-click the rule `(Default Rule) All files located in the Windows folder` and select </xhtml:em>
            <xhtml:em>Properties</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> On the </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for writeable directories under <xhtml:code>%WINDIR%</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Tasks\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\Temp\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\tracing\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\spool\drivers\color\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> `%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\</xhtml:em>
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> On the same </xhtml:em>
            <xhtml:em>Exceptions</xhtml:em>* tab, add path exceptions for the following bypass binaries (LOLBins):</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msbuild.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\installutil.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mshta.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regasm.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvcs.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\regsvr32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rundll32.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\bginfo.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cdb.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\cmstp.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\control.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\csi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dfsvc.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\dnx.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\fsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ie4unit.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\ieexec.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\infdefaultinstall.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\mavinject.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdeploy.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msdt.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\msxsl.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\odbcconf.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\presentationhost.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rcsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\rsi.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\runscripthelper.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\te.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\tracker.exe`</xhtml:li>
          <xhtml:li>
            <xhtml:em> `</xhtml:em>\xwizard.exe`</xhtml:li>
          <xhtml:li>Repeat the process for <xhtml:strong>Script Rules</xhtml:strong> by creating default rules and adding exceptions to the <xhtml:code>%WINDIR%\*</xhtml:code> Allow rule for script execution from user-writeable paths (such as <xhtml:code>%WINDIR%\Temp\*</xhtml:code> and <xhtml:code>%WINDIR%\Tasks\*</xhtml:code>).</xhtml:li>
          <xhtml:li>Disable NTVDM (16-bit application support) to prevent AppLocker bypasses via 16-bit binaries:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Administrative Templates\System\16-bit Application Compatibility</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Configure </xhtml:em>
            <xhtml:em>Prevent access to 16-bit applications</xhtml:em>
            <xhtml:em> to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Link the GPO to the Endpoints Organizational Unit (OU).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the Application Identity service (<xhtml:code>AppIDSvc</xhtml:code>) and import the robust AppLocker policy locally.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-EndpointAppLocker.ps1">Download Script: Configure-EndpointAppLocker.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndpointAppLocker.ps1
# Description: Configures the Application Identity service (AppIDSvc) to start automatically and imports a robust AppLocker XML policy.

Write-Host "Applying AppLocker Identity service hardening..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$AppLockerService = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($AppLockerService) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    Start-Service -Name AppIDSvc -ErrorAction SilentlyContinue
    Write-Host "[+] Application Identity Service (AppIDSvc) set to Automatic and started." -ForegroundColor Green
} else {
    Write-Warning "[-] Application Identity Service not found on this machine."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerEndpointPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the AppLocker service status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-EndpointAppLockerStatus.ps1">Download Script: Test-EndpointAppLockerStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-EndpointAppLockerStatus.ps1
# Description: Checks the current configuration and operational status of the Application Identity service.

Write-Host "--- Auditing AppLocker Service Status ---" -ForegroundColor Cyan

# 1. Audit service state
$AppIDSvc = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue

if ($AppIDSvc) {
    if ($AppIDSvc.Status -eq "Running" -and $AppIDSvc.StartType -eq "Automatic") {
        Write-Host "    - AppLocker Service Status: Running | Startup: Automatic (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: AppLocker Service Status: $($AppIDSvc.Status) | Startup: $($AppIDSvc.StartType) (Should be Running/Automatic)" -ForegroundColor Red
    }
} else {
    Write-Host "    - VULNERABLE: Application Identity Service (AppIDSvc) is not installed." -ForegroundColor Red
}

# 2. Audit enforcement registry settings
$SrpPath = "HKLM:\Software\Policies\Microsoft\Windows\SrpV2"
$Collections = @("Exe", "Msi", "Script", "Appx")

if (Test-Path $SrpPath) {
    foreach ($Col in $Collections) {
        $ColPath = "$SrpPath\$Col"
        if (Test-Path $ColPath) {
            $Val = Get-ItemProperty -Path $ColPath -Name "EnforcementMode" -ErrorAction SilentlyContinue
            if ($null -ne $Val) {
                $Mode = if ($Val.EnforcementMode -eq 1) { "Enforced" } else { "Audit Only" }
                $Color = if ($Val.EnforcementMode -eq 1) { "Green" } else { "Yellow" }
                Write-Host "    - Collection $Col Enforcement: $Mode (Value: $($Val.EnforcementMode))" -ForegroundColor $Color
            } else {
                Write-Host "    - Collection $Col Enforcement: NOT CONFIGURED" -ForegroundColor Red
            }
        } else {
            Write-Host "    - Collection $Col Path: NOT FOUND" -ForegroundColor Red
        }
    }
} else {
    Write-Host "[-] AppLocker registry base path (SrpV2) not found. Policy is not deployed." -ForegroundColor Red
}

# 3. Audit NTVDM Disable Status
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (Test-Path $NtvdmPath) {
    $AppCompatVal = Get-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -ErrorAction SilentlyContinue
    if ($null -ne $AppCompatVal -and $AppCompatVal.Prevent16BitApp -eq 1) {
        Write-Host "    - NTVDM (16-bit AppCompat): Disabled (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - NTVDM (16-bit AppCompat): Enabled or Not Configured (Expected: Disabled)" -ForegroundColor Yellow
    }
} else {
    Write-Host "    - NTVDM (16-bit AppCompat): Not Configured (Expected: Disabled)" -ForegroundColor Yellow
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-EndpointAppLocker.ps1
# Description: Configures the Application Identity service (AppIDSvc) to start automatically and imports a robust AppLocker XML policy.

Write-Host "Applying AppLocker Identity service hardening..." -ForegroundColor Cyan

# 1. Enable Application Identity service (AppIDSvc)
$AppLockerService = Get-Service -Name AppIDSvc -ErrorAction SilentlyContinue
if ($AppLockerService) {
    Set-Service -Name AppIDSvc -StartupType Automatic
    Start-Service -Name AppIDSvc -ErrorAction SilentlyContinue
    Write-Host "[+] Application Identity Service (AppIDSvc) set to Automatic and started." -ForegroundColor Green
} else {
    Write-Warning "[-] Application Identity Service not found on this machine."
}

# 2. Configure local AppLocker policy XML content
$AppLockerXml = @"
&lt;AppLockerPolicy Version="1"&gt;
  &lt;RuleCollection Type="Exe" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="921cc481-6e1e-453f-b3a5-bc4f4a38674d" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="a61c8b2c-6d8f-4ad9-acbc-467b78a7f7b4" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\tracing\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\spool\drivers\color\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter\*" /&gt;
        &lt;FilePathCondition Path="*\msbuild.exe" /&gt;
        &lt;FilePathCondition Path="*\installutil.exe" /&gt;
        &lt;FilePathCondition Path="*\mshta.exe" /&gt;
        &lt;FilePathCondition Path="*\regasm.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvcs.exe" /&gt;
        &lt;FilePathCondition Path="*\regsvr32.exe" /&gt;
        &lt;FilePathCondition Path="*\rundll32.exe" /&gt;
        &lt;FilePathCondition Path="*\bginfo.exe" /&gt;
        &lt;FilePathCondition Path="*\cdb.exe" /&gt;
        &lt;FilePathCondition Path="*\cmstp.exe" /&gt;
        &lt;FilePathCondition Path="*\control.exe" /&gt;
        &lt;FilePathCondition Path="*\csi.exe" /&gt;
        &lt;FilePathCondition Path="*\dfsvc.exe" /&gt;
        &lt;FilePathCondition Path="*\dnx.exe" /&gt;
        &lt;FilePathCondition Path="*\fsi.exe" /&gt;
        &lt;FilePathCondition Path="*\ie4unit.exe" /&gt;
        &lt;FilePathCondition Path="*\ieexec.exe" /&gt;
        &lt;FilePathCondition Path="*\infdefaultinstall.exe" /&gt;
        &lt;FilePathCondition Path="*\mavinject.exe" /&gt;
        &lt;FilePathCondition Path="*\msdeploy.exe" /&gt;
        &lt;FilePathCondition Path="*\msdt.exe" /&gt;
        &lt;FilePathCondition Path="*\msxsl.exe" /&gt;
        &lt;FilePathCondition Path="*\odbcconf.exe" /&gt;
        &lt;FilePathCondition Path="*\presentationhost.exe" /&gt;
        &lt;FilePathCondition Path="*\rcsi.exe" /&gt;
        &lt;FilePathCondition Path="*\rsi.exe" /&gt;
        &lt;FilePathCondition Path="*\runscripthelper.exe" /&gt;
        &lt;FilePathCondition Path="*\te.exe" /&gt;
        &lt;FilePathCondition Path="*\tracker.exe" /&gt;
        &lt;FilePathCondition Path="*\xwizard.exe" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="fd686d83-a829-4351-8ff4-27c1de5732e9" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Msi" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="5b8fa8b3-3a5e-4c7a-9cb8-b223ff9db271" Name="(Default Rule) All Windows Installer files in Program Files" Description="Allows everyone to run Windows Installer files in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="6b8fa8b3-3a5e-4c7a-9cb8-b223ff9db272" Name="(Default Rule) All Windows Installer files in Windows" Description="Allows everyone to run Windows Installer files in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="7b8fa8b3-3a5e-4c7a-9cb8-b223ff9db273" Name="(Default Rule) All Windows Installer files" Description="Allows administrators to run all Windows Installer files." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Script" EnforcementMode="Enabled"&gt;
    &lt;FilePathRule Id="1c8fa8b3-3a5e-4c7a-9cb8-b223ff9db274" Name="(Default Rule) All scripts located in the Program Files folder" Description="Allows everyone to run scripts in Program Files." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%PROGRAMFILES%\*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="2c8fa8b3-3a5e-4c7a-9cb8-b223ff9db275" Name="(Default Rule) All scripts located in the Windows folder" Description="Allows everyone to run scripts in Windows." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="%WINDIR%\*" /&gt;
      &lt;/Conditions&gt;
      &lt;Exceptions&gt;
        &lt;FilePathCondition Path="%WINDIR%\Temp\*" /&gt;
        &lt;FilePathCondition Path="%WINDIR%\Tasks\*" /&gt;
      &lt;/Exceptions&gt;
    &lt;/FilePathRule&gt;
    &lt;FilePathRule Id="3c8fa8b3-3a5e-4c7a-9cb8-b223ff9db276" Name="(Default Rule) All scripts" Description="Allows administrators to run all scripts." UserOrGroupSid="S-1-5-32-544" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePathCondition Path="*" /&gt;
      &lt;/Conditions&gt;
    &lt;/FilePathRule&gt;
  &lt;/RuleCollection&gt;
  &lt;RuleCollection Type="Appx" EnforcementMode="Enabled"&gt;
    &lt;FilePublisherRule Id="1d8fa8b3-3a5e-4c7a-9cb8-b223ff9db279" Name="(Default Rule) All signed packaged apps" Description="Allows everyone to run signed packaged apps." UserOrGroupSid="S-1-1-0" Action="Allow"&gt;
      &lt;Conditions&gt;
        &lt;FilePublisherCondition PublisherName="*" ProductName="*" BinaryName="*"&gt;
          &lt;BinaryVersionRange LowSection="0.0.0.0" HighSection="*" /&gt;
        &lt;/FilePublisherCondition&gt;
      &lt;/Conditions&gt;
    &lt;/FilePublisherRule&gt;
  &lt;/RuleCollection&gt;
&lt;/AppLockerPolicy&gt;
"@

# Write the temporary XML and import it
$TempPath = Join-Path -Path $env:TEMP -ChildPath "AppLockerEndpointPolicy.xml"
$AppLockerXml | Out-File -FilePath $TempPath -Encoding UTF8 -Force

# 3. Validate policy using Test-AppLockerPolicy before importing
try {
    Import-Module AppLocker -ErrorAction Stop
} catch {
    Write-Error "AppLocker module is not available on this system. Cannot configure or validate policy."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

$TestPaths = @(
    # Expected: Allowed
    "$env:windir\System32\cmd.exe",
    "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe",
    # Expected: DeniedByDefault or ExplicitlyDenied (since it is an exception to an Allow rule)
    "$env:USERPROFILE\Downloads\tool.exe",
    "$env:windir\Temp\malware.exe",
    "$env:windir\Tasks\evil.exe",
    "$env:windir\System32\msbuild.exe"
)

$ValidationFailed = $false
try {
    $TestResults = Test-AppLockerPolicy -XmlPolicy $TempPath -Path $TestPaths -User Everyone -ErrorAction Stop
    $ExpectedAllow = @(
        "$env:windir\System32\cmd.exe",
        "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    )
    $ExpectedDeny = @(
        "$env:USERPROFILE\Downloads\tool.exe",
        "$env:windir\Temp\malware.exe",
        "$env:windir\Tasks\evil.exe",
        "$env:windir\System32\msbuild.exe"
    )

    foreach ($Result in $TestResults) {
        $Path = $Result.FilePath
        $Decision = $Result.PolicyDecision
        if ($ExpectedAllow -contains $Path) {
            if ($Decision -ne "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Allow for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
        if ($ExpectedDeny -contains $Path) {
            if ($Decision -eq "Allowed") {
                Write-Warning "[VALIDATION FAIL] Expected Deny/Not Allowed for: $Path (got: $Decision)"
                $ValidationFailed = $true
            }
        }
    }
} catch {
    Write-Warning "Could not perform policy validation tests: $($_.Exception.Message)"
    $ValidationFailed = $true
}

if ($ValidationFailed) {
    Write-Error "AppLocker policy validation failed. Policy was NOT imported."
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
    return
}

Write-Host "[+] AppLocker policy validation passed. Proceeding with import." -ForegroundColor Green

# 4. Import the validated AppLocker policy
try {
    Set-AppLockerPolicy -XmlPolicy $TempPath -ErrorAction Stop
    Write-Host "[+] Local AppLocker policy imported and enforced successfully." -ForegroundColor Green
} catch {
    Write-Error "Failed to import AppLocker policy: $($_.Exception.Message)"
} finally {
    if (Test-Path $TempPath) {
        Remove-Item -Path $TempPath -Force
    }
}

# 5. Disable NTVDM (16-bit compatibility) via Registry
$NtvdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"
if (-not (Test-Path $NtvdmPath)) {
    New-Item -Path $NtvdmPath -Force | Out-Null
}
Set-ItemProperty -Path $NtvdmPath -Name "Prevent16BitApp" -Value 1 -Type DWord
Write-Host "[+] 16-bit NTVDM compatibility disabled in registry." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8027" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-028" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-028] Configure Early Launch Antimalware (ELAM) Policy</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and domain member servers. <xhtml:em>(For Domain Controllers, refer to [REQ-DC-156](../02-domain-controllers/configure-elam.md); for Privileged Access Workstations, refer to [REQ-PAW-014](../07-paws/configure-elam.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise, Windows 11 Enterprise, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-elam.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Standard enterprise endpoints and domain member servers represent the primary ingress point for adversaries seeking footholds inside an organization. Ensuring boot-level integrity prevents attackers from using persistence mechanisms that bypass user-mode security software.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the GPO applied to your standard endpoints and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Early Launch Antimalware</xhtml:code>
          </xhtml:li>
          <xhtml:li>In the right pane, double-click <xhtml:strong>Boot-Start Driver Initialization Policy</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>In the <xhtml:strong>Choose the boot-start drivers that can be initialized</xhtml:strong> dropdown, select:</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Good, unknown and bad but critical</xhtml:strong>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate <xhtml:strong>Endpoints</xhtml:strong> and <xhtml:strong>Member Servers</xhtml:strong> Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the ELAM boot-start driver load policy on endpoints.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-ElamPolicy.ps1">Download Script: Configure-ElamPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-ElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver load policy on the local system.

Write-Host "Applying ELAM Boot-Start driver initialization policy..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 3 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good, unknown and bad but critical' (Value = 3)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-ElamPolicy.ps1
# Description: Configures the Early Launch Antimalware (ELAM) boot-start driver load policy on the local system.

Write-Host "Applying ELAM Boot-Start driver initialization policy..." -ForegroundColor Cyan

$ElamPath = "HKLM:\SYSTEM\CurrentControlSet\Policies\EarlyLaunch"
if (-not (Test-Path $ElamPath)) {
    New-Item -Path $ElamPath -Force | Out-Null
}

Set-ItemProperty -Path $ElamPath -Name "DriverLoadPolicy" -Value 3 -Type DWord -ErrorAction Stop
Write-Host "[+] ELAM Boot-Start driver initialization policy set to 'Good, unknown and bad but critical' (Value = 3)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8028" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-029" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-029] Configure Untrusted Font Blocking</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-untrusted-font-blocking.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Font files (TrueType, OpenType, and others) are highly complex formats that require advanced parsing logic. Historically, font parsing in Windows was performed by the Graphics Device Interface (GDI) within the operating system kernel. Vulnerabilities in the kernel-mode font parser (such as buffer overflows or remote code execution) have been frequently exploited by threat actors to execute arbitrary code with kernel-level privileges.</xhtml:p>
        <xhtml:p>Enabling Untrusted Font Blocking limits the attack surface of the graphics subsystem: 1. <xhtml:strong>Kernel Attack Surface Reduction</xhtml:strong>: Restricting the system to only load trusted fonts installed in the <xhtml:code>%windir%\Fonts</xhtml:code> system directory prevents the processing of malicious, web-delivered, or embedded font files. 2. <xhtml:strong>Mitigation of Document-Based Exploits</xhtml:strong>: Prevents malicious font files embedded in Microsoft Office documents, PDFs, or web pages from triggering parsing vulnerabilities in the context of the current user.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain controller or management host.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing one (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Mitigation Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Untrusted Font Blocking</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Mitigation Options</xhtml:em>*: <xhtml:code>Block untrusted fonts and log events</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) containing the target client endpoints and member servers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally on standalone systems or during reference image build phases.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-UntrustedFontBlocking.ps1">Download Script: Configure-UntrustedFontBlocking.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-UntrustedFontBlockingStatus.ps1">Download Script: Get-UntrustedFontBlockingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-UntrustedFontBlockingStatus.ps1
# Description: Checks the current configuration state of Untrusted Font Blocking registry setting.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ExpectedValue = "1000000000000"

Write-Host "Auditing hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (Test-Path $RegPath) {
    $value = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $value -and $value.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. Untrusted fonts are blocked and logged ($($ValueName) = $($ExpectedValue))." -ForegroundColor Green
        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. Untrusted fonts are not configured to block and log." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-UntrustedFontBlocking.ps1
# Description: Configures Untrusted Font Blocking mitigation to block untrusted fonts and log events.

$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions"
$ValueName = "MitigationOptions_FontBocking"
$ValueData = "1000000000000"

Write-Host "Applying hardening requirement: Configure Untrusted Font Blocking..." -ForegroundColor Cyan

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type String -Force | Out-Null
Write-Host "Hardening applied successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8029" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-030" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-030] Configure svchost.exe Mitigation Options</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations. <xhtml:em>(For Domain Controllers and Domain Member Servers, refer to [REQ-DC-029](../02-domain-controllers/configure-svchost-mitigation.md); for Privileged Access Workstations, refer to [REQ-PAW-017](../07-paws/configure-svchost-mitigation.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (1903 and above), Windows 11 Enterprise/Professional.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-svchost-mitigation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Service Host (<xhtml:code>svchost.exe</xhtml:code>) process is a fundamental Windows operating system binary designed to host one or more shared or isolated system services. Because <xhtml:code>svchost.exe</xhtml:code> instances execute with elevated privileges (such as <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>, <xhtml:code>NT AUTHORITY\LOCAL SERVICE</xhtml:code>, or <xhtml:code>NT AUTHORITY\NETWORK SERVICE</xhtml:code>) and naturally maintain persistent execution across user sessions, they represent one of the primary targets for threat actors seeking privilege escalation, defense evasion, and persistence on client workstations.</xhtml:p>
        <xhtml:p>In client endpoint environments, workstations serve as the primary initial access vector for attackers through phishing attachments, malicious browser downloads, drive-by exploits, or compromised peripheral devices. Once a basic user-level foothold is achieved, adversaries frequently attempt to blend malicious activity into legitimate system traffic by targeting <xhtml:code>svchost.exe</xhtml:code>: 1. <xhtml:strong>Process Injection &amp; Hollowing (MITRE ATT&amp;CK T1055, T1055.012)</xhtml:strong>: Attackers create a suspended <xhtml:code>svchost.exe</xhtml:code> process or inject malicious code into an existing service host instance (<xhtml:code>CreateRemoteThread</xhtml:code>, <xhtml:code>QueueUserAPC</xhtml:code>, <xhtml:code>SetThreadContext</xhtml:code>). This disguises command-and-control (C2) beaconing (e.g., Cobalt Strike, Sliver, Brute Ratel) under trusted system process names and bypasses basic endpoint security inspection. 2. <xhtml:strong>Dynamic Code Execution &amp; Reflective Loading</xhtml:strong>: In-memory payloads and exploitation frameworks rely on allocating executable memory (<xhtml:code>PAGE_EXECUTE_READWRITE</xhtml:code> via <xhtml:code>VirtualAlloc</xhtml:code> or <xhtml:code>VirtualProtect</xhtml:code>) to dynamically decrypt, compile, or inject unmapped DLLs directly into process memory without touching disk. 3. <xhtml:strong>Ghost Service DLL Hijacking &amp; Malicious Service Registration (MITRE ATT&amp;CK T1574.002)</xhtml:strong>: Attackers modify service registry keys to point <xhtml:code>ServiceDll</xhtml:code> to unsigned, arbitrary third-party DLLs. When the Service Control Manager starts the service, <xhtml:code>svchost.exe</xhtml:code> loads the unauthorized DLL with SYSTEM privileges.</xhtml:p>
        <xhtml:p>Enabling <xhtml:code>svchost.exe</xhtml:code> mitigation options instructs the Windows Service Control Manager (SCM, <xhtml:code>services.exe</xhtml:code>) to apply strict kernel-enforced process creation mitigation policies whenever a new <xhtml:code>svchost.exe</xhtml:code> instance is spawned: <xhtml:em> </xhtml:em>
          <xhtml:em>Microsoft-Only Binary Enforcement (`PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON`)</xhtml:em>
          <xhtml:em>: Enforces that every executable binary and Dynamic Link Library (DLL) loaded into the address space of any `svchost.exe` process must be digitally signed by a trusted Microsoft certificate (Windows Production Root, WHQL, or Microsoft Corporation). Any attempt by unsigned, self-signed, or third-party binaries to map into `svchost.exe` is immediately terminated by the Windows kernel with `STATUS_INVALID_IMAGE_HASH` (`0xC0000428`). </xhtml:em>
          <xhtml:strong>Dynamic Code Execution Blocking (`PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON`)</xhtml:strong>: Disallows the generation and execution of dynamic code within <xhtml:code>svchost.exe</xhtml:code> processes. This kernel mitigation blocks arbitrary memory page execution, preventing JIT compilation abuse, shellcode execution, and reflective DLL injection inside all system service containers. <xhtml:em> </xhtml:em>
          <xhtml:em>Service Host Splitting Synergies</xhtml:em>*: Since Windows 10 Version 1703, on workstations with more than 3.5 GB of RAM (<xhtml:code>SvcHostSplitThresholdInKB</xhtml:code>), Windows automatically isolates individual services into dedicated, standalone <xhtml:code>svchost.exe</xhtml:code> processes. When <xhtml:code>EnableSvchostMitigationPolicy</xhtml:code> is active, this per-service architecture ensures that every isolated service process receives independent, uncompromising mitigation enforcement.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on an administrative workstation or Domain Controller.</xhtml:li>
          <xhtml:li>Create a new GPO or edit an existing endpoint hardening GPO (e.g., <xhtml:code>GPO_Hardening_Tier2_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Service Control Manager Settings\Security Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>In the right-hand details pane, double-click <xhtml:strong>Enable svchost.exe mitigation options</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the Organizational Unit (OU) containing your Tier 2 client workstations (e.g., <xhtml:code>OU=Workstations,DC=contoso,DC=com</xhtml:code>).</xhtml:li>
          <xhtml:li>After applying the policy, schedule or initiate a system restart on target endpoints to enforce the mitigation policy across all boot-level service host instances.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally during gold master image creation, automated Intune / MDM provisioning, or standalone testing.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-SvchostMitigation.ps1">Download Script: Configure-SvchostMitigation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows Server 2022 / Build 20348)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows 10 1903+ or Windows Server 2022+)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options: $($_.Exception.Message)"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-SvchostMitigationStatus.ps1">Download Script: Get-SvchostMitigationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-SvchostMitigationStatus.ps1
# Description: Audits the configuration state of svchost.exe mitigation options.

[CmdletBinding()]
param()

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ExpectedValue = 1

Write-Host "Auditing hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "Audit Result: Non-Applicable / Unsupported. OS build $($osBuild) precedes the introduction of svchost mitigation policy (requires Windows 10 1903+ or Windows Server 2022+)."
    exit 1
}

if (Test-Path -Path $RegPath) {
    $item = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $item -and $item.$ValueName -eq $ExpectedValue) {
        Write-Host "Audit Result: Compliant. svchost.exe mitigation policy is enabled in registry ($($RegPath)\$($ValueName) = 1)." -ForegroundColor Green

        # Optional check for running svchost processes
        $svchostProcesses = Get-Process -Name "svchost" -ErrorAction SilentlyContinue
        if ($svchostProcesses) {
            Write-Host "Found $($svchostProcesses.Count) running svchost.exe process instances. Process mitigation flags are enforced dynamically at process spawn by the Service Control Manager." -ForegroundColor Gray
        }

        exit 0
    }
}

Write-Host "Audit Result: Non-Compliant. svchost.exe mitigation options are disabled or not configured ($($RegPath)\$($ValueName))." -ForegroundColor Red
exit 1</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-SvchostMitigation.ps1
# Description: Configures svchost.exe mitigation options to enforce Microsoft-signed binaries and block dynamic code.

[CmdletBinding()]
param()

$ErrorActionPreference = "Stop"

Write-Host "Applying hardening requirement: Configure svchost.exe mitigation options..." -ForegroundColor Cyan

# Verify minimum operating system build compatibility (Windows 10 1903 / Build 18362 or Windows Server 2022 / Build 20348)
$osVersion = [System.Environment]::OSVersion.Version
$osBuild = $osVersion.Build

if ($osBuild -lt 18362) {
    Write-Warning "The operating system build ($($osBuild)) does not support EnableSvchostMitigationPolicy (requires Windows 10 1903+ or Windows Server 2022+)."
    exit 1
}

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SCMConfig"
$ValueName = "EnableSvchostMitigationPolicy"
$ValueData = 1

try {
    if (-not (Test-Path -Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Host "Created registry key: $($RegPath)" -ForegroundColor Gray
    }

    Set-ItemProperty -Path $RegPath -Name $ValueName -Value $ValueData -Type DWord -Force | Out-Null

    # Validate written value
    $configuredValue = (Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction Stop).$ValueName
    if ($configuredValue -eq $ValueData) {
        Write-Host "Hardening applied successfully: $($ValueName) set to 1." -ForegroundColor Green
        Write-Host "Note: This policy applies to newly created svchost.exe instances. A full system restart is required to protect services initialized at system boot." -ForegroundColor Yellow
        exit 0
    } else {
        throw "Failed to verify registry property value after write."
    }
} catch {
    Write-Error "Error configuring svchost.exe mitigation options: $($_.Exception.Message)"
    exit 1
}</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8030" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-031" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-031] Enable Kernel-Mode Hardware-Enforced Stack Protection</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 11 (and above) Enterprise/Professional</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-kernel-shadow-stacks.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kernel-mode Hardware-enforced Stack Protection uses CPU hardware features to protect the operating system kernel from memory corruption exploits, specifically Return-Oriented Programming (ROP) attacks.</xhtml:p>
        <xhtml:p>An adversary attempting privilege escalation or remote code execution often hijacks the control flow of kernel-mode components by overwriting return addresses on the stack. Intel Control-flow Enforcement Technology (CET) and AMD Shadow Stack technologies create a separate, hardware-secured copy of the call stack (the "shadow stack").</xhtml:p>
        <xhtml:p>Before returning from a function, the CPU compares the return address on the standard stack with the address stored on the hardware-secured shadow stack. If the addresses do not match, the processor detects a control flow violation, terminates the process, or triggers a system crash to prevent execution of malicious payloads.</xhtml:p>
        <xhtml:p>Enforcing Kernel-mode Hardware-enforced Stack Protection provides hardware-backed control-flow integrity, neutralizing key vectors of kernel exploitation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the appropriate endpoint GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Turn On Virtualization Based Security` -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Kernel-level shadow stacks</xhtml:em>
            <xhtml:em> -&gt; Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (or set registry <xhtml:code>Enabled</xhtml:code> = <xhtml:code>1</xhtml:code>)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the registry and activate Kernel-mode Hardware-enforced Stack Protection.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Enable-KernelShadowStacks.ps1">Download Script: Enable-KernelShadowStacks.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Enable-KernelShadowStacks.ps1
# Description: Configures HKLM registry to enable Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks).

Write-Host "Enabling Kernel-mode Hardware-enforced Stack Protection..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "Enabled" -Value 1 -Type DWord
Write-Host "[+] Registry setting for Kernel Shadow Stacks enabled. (Reboot required)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the state of Kernel-mode Hardware-enforced Stack Protection:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Test-KernelShadowStacks.ps1">Download Script: Test-KernelShadowStacks.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Test-KernelShadowStacks.ps1
# Description: Audits the registry status of Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks).

Write-Host "--- Auditing Kernel-mode Hardware-enforced Stack Protection ---" -ForegroundColor Cyan

$script:Vulnerable = $false
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

# Check registry value
$val = Get-ItemProperty -Path $RegPath -Name "Enabled" -ErrorAction SilentlyContinue
$actual = if ($val) { $val.Enabled } else { "" }

if ($actual -eq 1) {
    Write-Host "    - Registry Setting: KernelShadowStacks Enabled | Actual: '1' (Expected: '1')" -ForegroundColor Green
} else {
    $script:Vulnerable = $true
    Write-Host "    - Registry Setting: KernelShadowStacks Enabled | Actual: '$actual' (Expected: '1')" -ForegroundColor Red
}

# Verify VBS dependency is met
try {
    $DG = Get-CimInstance -Namespace "Root\Microsoft\Windows\DeviceGuard" -ClassName "Win32_DeviceGuard" -ErrorAction Stop
    if ($DG.VirtualizationBasedSecurityStatus -eq 2) {
        Write-Host "    - VBS Status: Running" -ForegroundColor Green
    } else {
        $script:Vulnerable = $true
        Write-Host "    - VBS Status: Not Running (VBS is required for Kernel Shadow Stacks)" -ForegroundColor Red
    }
} catch {
    $script:Vulnerable = $true
    Write-Host "    - DeviceGuard WMI class query failed. VBS is likely disabled." -ForegroundColor Red
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Enable-KernelShadowStacks.ps1
# Description: Configures HKLM registry to enable Kernel-mode Hardware-enforced Stack Protection (Kernel Shadow Stacks).

Write-Host "Enabling Kernel-mode Hardware-enforced Stack Protection..." -ForegroundColor Cyan

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\KernelShadowStacks"

if (-not (Test-Path $RegPath)) {
    New-Item -Path $RegPath -Force | Out-Null
}

Set-ItemProperty -Path $RegPath -Name "Enabled" -Value 1 -Type DWord
Write-Host "[+] Registry setting for Kernel Shadow Stacks enabled. (Reboot required)." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8031" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-032" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-032] Disable Unused Windows Features and PowerShell 2.0 Engine</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/disable-unused-features.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>To minimize the attack surface of standard client endpoints and member servers, all unnecessary legacy protocols, optional features, and runtime engines must be disabled:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>PowerShell 2.0 Engine</xhtml:strong>: Legacy PowerShell 2.0 does not support modern logging, transcription, or security monitoring mechanisms such as the Antimalware Scan Interface (AMSI). Attackers leverage "downgrade attacks" by executing PowerShell scripts using the <xhtml:code>-version 2.0</xhtml:code> parameter to bypass script block logging and security tooling. Disabling the engine and its parent runtimes eliminates this bypass vector.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>.NET Framework 3.5</xhtml:strong>: The .NET 3.5 Framework includes the runtime files for .NET 2.0 and 3.0. PowerShell 2.0 requires .NET 2.0/3.5 to run. Disabling <xhtml:code>.NET Framework 3.5</xhtml:code> removes legacy runtime binaries that are susceptible to downgrade attacks and removes support for older, unpatched software.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>SMBv1 Protocol</xhtml:strong>: The legacy SMBv1 protocol is cryptographically weak, lacks authentication integrity protection, and has been the target of catastrophic remote code execution attacks (such as EternalBlue). Leaving the SMBv1 driver active allows relaying and man-in-the-middle attacks.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Internet Explorer 11</xhtml:strong>: Internet Explorer contains obsolete MSHTML render engine components. Disabling this legacy browser reduces vulnerability to web-based code execution.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Work Folders, XPS, DirectPlay, and Client Protocols</xhtml:strong>: Services and tools such as Work Folders, XPS Viewer, DirectPlay, Telnet Client, TFTP Client, and Simple TCP/IP Services contain legacy network parsers and protocols that are completely unnecessary for a secure administrative system.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Disable PowerShell 2.0 Compatibility Policy</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a management host.</xhtml:li>
          <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows PowerShell</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Turn on PowerShell 2.0 Compatibility Mode</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the Endpoints and Member Servers OUs.</xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Deploy Feature Disablement Startup Script</xhtml:h4>
        <xhtml:p>Because Windows Optional Features are managed via DISM/Packages and lack direct GPO settings for feature removal, deploy the disablement script as a Computer Startup script: 1. In the same GPO, navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Scripts (Startup/Shutdown)</xhtml:code> 2. Double-click <xhtml:strong>Startup</xhtml:strong>, click the <xhtml:strong>PowerShell Scripts</xhtml:strong> tab. 3. Add the <xhtml:code>Disable-UnusedFeatures.ps1</xhtml:code> script to execute on system startup.</xhtml:p>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally or run it as a startup script.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-UnusedFeatures.ps1">Download Script: Disable-UnusedFeatures.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-UnusedFeatures.ps1
# Description: Disables unused legacy features, .NET 3.5, and PowerShell 2.0 on the local system.

Write-Host "Disabling unused legacy features and PowerShell 2.0..." -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

# Feature lists
$DismFeatures = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP"                              # Simple TCP/IP Services
)

$ServerFeatures = @(
    "PowerShell-V2",
    "NET-Framework-Core",
    "FS-SMB1",
    "Internet-Explorer-Optional-amd64",
    "WorkFolders-Client",
    "Xps-Viewer-Dependency",
    "DirectPlay",
    "Telnet-Client",
    "TFTP-Client",
    "Simple-TCPIP"
)

if (Get-Command Get-WindowsFeature -ErrorAction SilentlyContinue) {
    # Windows Server path
    foreach ($FeatName in $ServerFeatures) {
        $Feat = Get-WindowsFeature -Name $FeatName -ErrorAction SilentlyContinue
        if ($null -ne $Feat) {
            if ($Feat.Installed) {
                Write-Host "[*] Removing Server feature: $FeatName..." -ForegroundColor Yellow
                Uninstall-WindowsFeature -Name $FeatName -ErrorAction SilentlyContinue | Out-Null
                Write-Host "[+] Feature '$FeatName' uninstalled." -ForegroundColor Green
            } else {
                Write-Host "[~] Feature '$FeatName' is already uninstalled." -ForegroundColor Gray
            }
        } else {
            # Try DISM fallback
            $DismFeat = Get-WindowsOptionalFeature -Online -FeatureName $FeatName -ErrorAction SilentlyContinue
            if ($null -ne $DismFeat) {
                if ($DismFeat.State -eq "Enabled" -or $DismFeat.State -eq "EnabledPendingRestart") {
                    Write-Host "[*] Disabling optional feature: $FeatName..." -ForegroundColor Yellow
                    Disable-WindowsOptionalFeature -Online -FeatureName $FeatName -NoRestart -ErrorAction SilentlyContinue | Out-Null
                    Write-Host "[+] Feature '$FeatName' disabled." -ForegroundColor Green
                } else {
                    Write-Host "[~] Feature '$FeatName' is already disabled." -ForegroundColor Gray
                }
            } else {
                Write-Host "[~] Feature '$FeatName' is not present in the system." -ForegroundColor Gray
            }
        }
    }
} else {
    # Windows Client path
    foreach ($Feature in $DismFeatures) {
        $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
        if ($null -ne $State) {
            if ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart") {
                Write-Host "[*] Disabling feature: $Feature..." -ForegroundColor Yellow
                Disable-WindowsOptionalFeature -Online -FeatureName $Feature -NoRestart -ErrorAction SilentlyContinue | Out-Null
                Write-Host "[+] Feature '$Feature' has been disabled." -ForegroundColor Green
            } else {
                Write-Host "[~] Feature '$Feature' is already disabled." -ForegroundColor Gray
            }
        } else {
            Write-Host "[~] Feature '$Feature' is not present in this Windows image." -ForegroundColor Gray
        }
    }
}

Write-Host "Optional features configuration completed." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the state of unused features:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-UnusedFeaturesStatus.ps1">Download Script: Get-UnusedFeaturesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-UnusedFeaturesStatus.ps1
# Description: Audits the installation state of unused legacy features on the local system.

Write-Host "--- Auditing Unused Windows Features ---" -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

$script:Vulnerable = $false

$DismFeatures = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP"                              # Simple TCP/IP Services
)

$ServerFeatures = @(
    "PowerShell-V2",
    "NET-Framework-Core",
    "FS-SMB1",
    "Internet-Explorer-Optional-amd64",
    "WorkFolders-Client",
    "Xps-Viewer-Dependency",
    "DirectPlay",
    "Telnet-Client",
    "TFTP-Client",
    "Simple-TCPIP"
)

if (Get-Command Get-WindowsFeature -ErrorAction SilentlyContinue) {
    # Windows Server path
    foreach ($FeatName in $ServerFeatures) {
        $Feat = Get-WindowsFeature -Name $FeatName -ErrorAction SilentlyContinue
        if ($null -ne $Feat) {
            $Color = if ($Feat.Installed -eq $false) { "Green" } else { "Red" }
            Write-Host "    - Feature: $FeatName | Installed: $($Feat.Installed) (Expected: False)" -ForegroundColor $Color
            if ($Feat.Installed) {
                $script:Vulnerable = $true
            }
        } else {
            # Try DISM fallback
            $DismFeat = Get-WindowsOptionalFeature -Online -FeatureName $FeatName -ErrorAction SilentlyContinue
            if ($null -ne $DismFeat) {
                $IsEnabled = ($DismFeat.State -eq "Enabled" -or $DismFeat.State -eq "EnabledPendingRestart")
                $Color = if (-not $IsEnabled) { "Green" } else { "Red" }
                Write-Host "    - Feature: $FeatName (DISM) | State: $($DismFeat.State) (Expected: Disabled)" -ForegroundColor $Color
                if ($IsEnabled) {
                    $script:Vulnerable = $true
                }
            } else {
                Write-Host "    - Feature: $FeatName | Not Present (Compliant)" -ForegroundColor Green
            }
        }
    }
} else {
    # Windows Client path
    foreach ($Feature in $DismFeatures) {
        $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
        if ($null -ne $State) {
            $IsEnabled = ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart")
            $Color = if (-not $IsEnabled) { "Green" } else { "Red" }
            Write-Host "    - Feature: $Feature | State: $($State.State) (Expected: Disabled)" -ForegroundColor $Color
            
            if ($IsEnabled) {
                $script:Vulnerable = $true
            }
        } else {
            Write-Host "    - Feature: $Feature | Not Present (Compliant)" -ForegroundColor Green
        }
    }
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-UnusedFeatures.ps1
# Description: Disables unused legacy features, .NET 3.5, and PowerShell 2.0 on the local system.

Write-Host "Disabling unused legacy features and PowerShell 2.0..." -ForegroundColor Cyan

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Error "This script must be run as an Administrator."
    exit 1
}

# Feature lists
$DismFeatures = @(
    "MicrosoftWindowsPowerShellV2",
    "MicrosoftWindowsPowerShellV2Root",
    "NetFx3",                                # .NET Framework 3.5
    "SMB1Protocol",                          # SMBv1 Client
    "Internet-Explorer-Optional-amd64",      # Internet Explorer 11
    "WorkFolders-Client",                    # Work Folders Client
    "Xps-Viewer-Dependency",                 # XPS Viewer
    "DirectPlay",                            # DirectPlay
    "TelnetClient",                          # Telnet Client
    "TFTP",                                  # TFTP Client
    "SimpleTCP"                              # Simple TCP/IP Services
)

$ServerFeatures = @(
    "PowerShell-V2",
    "NET-Framework-Core",
    "FS-SMB1",
    "Internet-Explorer-Optional-amd64",
    "WorkFolders-Client",
    "Xps-Viewer-Dependency",
    "DirectPlay",
    "Telnet-Client",
    "TFTP-Client",
    "Simple-TCPIP"
)

if (Get-Command Get-WindowsFeature -ErrorAction SilentlyContinue) {
    # Windows Server path
    foreach ($FeatName in $ServerFeatures) {
        $Feat = Get-WindowsFeature -Name $FeatName -ErrorAction SilentlyContinue
        if ($null -ne $Feat) {
            if ($Feat.Installed) {
                Write-Host "[*] Removing Server feature: $FeatName..." -ForegroundColor Yellow
                Uninstall-WindowsFeature -Name $FeatName -ErrorAction SilentlyContinue | Out-Null
                Write-Host "[+] Feature '$FeatName' uninstalled." -ForegroundColor Green
            } else {
                Write-Host "[~] Feature '$FeatName' is already uninstalled." -ForegroundColor Gray
            }
        } else {
            # Try DISM fallback
            $DismFeat = Get-WindowsOptionalFeature -Online -FeatureName $FeatName -ErrorAction SilentlyContinue
            if ($null -ne $DismFeat) {
                if ($DismFeat.State -eq "Enabled" -or $DismFeat.State -eq "EnabledPendingRestart") {
                    Write-Host "[*] Disabling optional feature: $FeatName..." -ForegroundColor Yellow
                    Disable-WindowsOptionalFeature -Online -FeatureName $FeatName -NoRestart -ErrorAction SilentlyContinue | Out-Null
                    Write-Host "[+] Feature '$FeatName' disabled." -ForegroundColor Green
                } else {
                    Write-Host "[~] Feature '$FeatName' is already disabled." -ForegroundColor Gray
                }
            } else {
                Write-Host "[~] Feature '$FeatName' is not present in the system." -ForegroundColor Gray
            }
        }
    }
} else {
    # Windows Client path
    foreach ($Feature in $DismFeatures) {
        $State = Get-WindowsOptionalFeature -Online -FeatureName $Feature -ErrorAction SilentlyContinue
        if ($null -ne $State) {
            if ($State.State -eq "Enabled" -or $State.State -eq "EnabledPendingRestart") {
                Write-Host "[*] Disabling feature: $Feature..." -ForegroundColor Yellow
                Disable-WindowsOptionalFeature -Online -FeatureName $Feature -NoRestart -ErrorAction SilentlyContinue | Out-Null
                Write-Host "[+] Feature '$Feature' has been disabled." -ForegroundColor Green
            } else {
                Write-Host "[~] Feature '$Feature' is already disabled." -ForegroundColor Gray
            }
        } else {
            Write-Host "[~] Feature '$Feature' is not present in this Windows image." -ForegroundColor Gray
        }
    }
}

Write-Host "Optional features configuration completed." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8032" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-033" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-033] Configure Microsoft Office Security and Block OLE Packages</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Member Workstations (Endpoints)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-office-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Malicious documents (e.g., weaponized Word, Excel, or PowerPoint files) containing embedded VBA macros are a prevalent initial access and execution vector. Similarly, embedding malicious OLE packages inside Outlook items (such as RTF-formatted emails) allows attackers to trigger script execution or execute arbitrary packages via <xhtml:code>packager.dll</xhtml:code> when an administrator or standard user opens or previews the email.</xhtml:p>
        <xhtml:p>Hardening these settings ensures: 1. <xhtml:strong>Internet Macro Blocking</xhtml:strong>: VBA macros in files downloaded from the Internet or untrusted external attachments are blocked from executing, regardless of user consent. 2. <xhtml:strong>Macro Code Signing</xhtml:strong>: Any locally run macros are restricted to trusted, digitally signed code, preventing the execution of ad-hoc unverified user scripts. 3. <xhtml:strong>OLE Package Disablement</xhtml:strong>: Restricting Outlook OLE package activation (<xhtml:code>ShowOLEPackageObj = 0</xhtml:code>) blocks the execution of dangerous embedded objects in email messages.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Enforce Macro Security in ADMX Templates</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the target endpoints GPO.</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Policies\Administrative Templates\Microsoft Office 2016\Security Settings\Trust Center</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `VBA Macro Notification Settings` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em> with option set to </xhtml:em>
            <xhtml:em>Disable all except digitally signed macros</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>For each application (Word, Excel, PowerPoint, Access), navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>User Configuration\Policies\Administrative Templates\[Application] 2016\[Application] Options\Security\Trust Center</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set the policy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Block macros from running in Office files from the Internet` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Disable Outlook OLE Packages</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Policies\Administrative Templates\Microsoft Outlook 2016\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Do not allow OLE package execution` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the current user registry hives to enforce macro blocking and OLE package restrictions.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-OfficeSecurity.ps1">Download Script: Configure-OfficeSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-OfficeSecurity.ps1
# Description: Configures registry settings under the HKCU hive to restrict VBA macros and block Outlook OLE package execution.

Write-Host "Applying Microsoft Office security and OLE restrictions..." -ForegroundColor Cyan

# Helper to configure User Registry DWORD values
function Set-UserRegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$Path,
        [string]$Name,
        [int]$Value
    )
    if ($PSCmdlet.ShouldProcess($Path, "Set registry DWORD value $Name to $Value")) {
        $FullRegistryPath = "HKCU:\$Path"
        if (-not (Test-Path $FullRegistryPath)) {
            New-Item -Path $FullRegistryPath -Force | Out-Null
        }
        Set-ItemProperty -Path $FullRegistryPath -Name $Name -Value $Value -Type DWord -Force
    }
}

# 1. Enforce macro signing policy (common)
Set-UserRegDWord "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3
Write-Host "[+] Digital signing for Office macros enforced." -ForegroundColor Green

# 2. Block macros from the Internet for key Office applications
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Set-UserRegDWord "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}
Write-Host "[+] VBA macro blocks from Internet applied to Office applications." -ForegroundColor Green

# 3. Disable OLE Package execution in Outlook (Policies and Preferences branches)
Set-UserRegDWord "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Set-UserRegDWord "software\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Write-Host "[+] Outlook OLE Package execution blocked." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the current Office security settings:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-OfficeSecurityStatus.ps1">Download Script: Get-OfficeSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-OfficeSecurityStatus.ps1
# Description: Audits Microsoft Office macro settings and Outlook OLE package restrictions.

Write-Host "--- Auditing Microsoft Office Security Baseline ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# Helper to audit registry values under HKCU
function Test-UserRegistryValue ($Path, $Name, $ExpectedValue) {
    $FullRegistryPath = "HKCU:\$Path"
    $Val = Get-ItemProperty -Path $FullRegistryPath -Name $Name -ErrorAction SilentlyContinue
    $Actual = if ($val) { $val.$Name } else { "" }
    $Color = "Red"
    if ($Actual -eq $ExpectedValue) {
        $Color = "Green"
    } else {
        $script:Vulnerable = $true
    }
    Write-Host "    - User Registry: $Name | Actual: '$Actual' (Expected: '$ExpectedValue')" -ForegroundColor $Color
}

# 1. Audit macro signing warning
Test-UserRegistryValue "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3

# 2. Audit macro Internet blocks
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Test-UserRegistryValue "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}

# 3. Audit Outlook OLE package block
Test-UserRegistryValue "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-OfficeSecurity.ps1
# Description: Configures registry settings under the HKCU hive to restrict VBA macros and block Outlook OLE package execution.

Write-Host "Applying Microsoft Office security and OLE restrictions..." -ForegroundColor Cyan

# Helper to configure User Registry DWORD values
function Set-UserRegDWord {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$Path,
        [string]$Name,
        [int]$Value
    )
    if ($PSCmdlet.ShouldProcess($Path, "Set registry DWORD value $Name to $Value")) {
        $FullRegistryPath = "HKCU:\$Path"
        if (-not (Test-Path $FullRegistryPath)) {
            New-Item -Path $FullRegistryPath -Force | Out-Null
        }
        Set-ItemProperty -Path $FullRegistryPath -Name $Name -Value $Value -Type DWord -Force
    }
}

# 1. Enforce macro signing policy (common)
Set-UserRegDWord "software\policies\microsoft\office\16.0\common\security" "vbawarnings" 3
Write-Host "[+] Digital signing for Office macros enforced." -ForegroundColor Green

# 2. Block macros from the Internet for key Office applications
$Apps = @("excel", "word", "powerpoint", "access", "visio")
foreach ($App in $Apps) {
    Set-UserRegDWord "software\policies\microsoft\office\16.0\$App\security" "blockcontentexecutionfrominternet" 1
}
Write-Host "[+] VBA macro blocks from Internet applied to Office applications." -ForegroundColor Green

# 3. Disable OLE Package execution in Outlook (Policies and Preferences branches)
Set-UserRegDWord "software\policies\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Set-UserRegDWord "software\microsoft\office\16.0\outlook\security" "ShowOLEPackageObj" 0
Write-Host "[+] Outlook OLE Package execution blocked." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8033" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-034" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-034] Disable Windows Script Host and Remap Scripting Extensions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Member Workstations (Endpoints - Tier 2 Client Workstations and Laptops). <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-034](../07-paws/disable-windows-script-host.md); for Tier 0 Domain Controllers and Member Servers, refer to [REQ-DC-159](../02-domain-controllers/disable-windows-script-host.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise (1809+), Windows 11 Enterprise (all supported builds).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/disable-windows-script-host.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Script Host (WSH), encompassing the <xhtml:code>wscript.exe</xhtml:code> (graphical) and <xhtml:code>cscript.exe</xhtml:code> (command-line) host engines, executes legacy scripting languages including VBScript (<xhtml:code>vbscript.dll</xhtml:code>) and JScript (<xhtml:code>jscript.dll</xhtml:code>). In client endpoint environments, WSH is one of the most heavily abused Living-off-the-Land Binaries (LOLBins / LOLBAS) leveraged by adversaries for initial access, defense evasion, and payload execution (MITRE ATT&amp;CK T1059.005, T1059.007, T1218):</xhtml:p>
        <xhtml:ol>
          <xhtml:li>
            <xhtml:strong>Initial Access via Phishing and Drive-By Downloads</xhtml:strong>: Threat actors routinely deliver weaponized script files (such as <xhtml:code>.vbs</xhtml:code>, <xhtml:code>.js</xhtml:code>, <xhtml:code>.wsf</xhtml:code>, <xhtml:code>.hta</xhtml:code>) disguised as business invoices, delivery notifications, or archived attachments inside ZIP/ISO files. When an unsuspecting user double-clicks such a file, Windows Explorer automatically invokes <xhtml:code>wscript.exe</xhtml:code> or <xhtml:code>mshta.exe</xhtml:code>, running malicious code directly in the user's security context without prompting.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Attack Surface Reduction</xhtml:strong>: Disabling WSH globally via the <xhtml:code>Enabled = 0</xhtml:code> registry parameter completely blocks <xhtml:code>wscript.exe</xhtml:code> and <xhtml:code>cscript.exe</xhtml:code> from executing any VBScript or JScript files system-wide, producing an immediate termination notice if an execution attempt is made.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>64-Bit and 32-Bit WOW6432Node Coverage</xhtml:strong>: On 64-bit Windows architectures, 32-bit applications and sub-processes invoke the 32-bit scripting host located in <xhtml:code>%SystemRoot%\SysWOW64\wscript.exe</xhtml:code>. Applying the <xhtml:code>Enabled = 0</xhtml:code> and <xhtml:code>TrustPolicy = 2</xhtml:code> registry values to both the native 64-bit hive (<xhtml:code>HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>) and the 32-bit registry hive (<xhtml:code>HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>) guarantees that 32-bit sub-processes cannot be weaponized as an evasion tactic.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>TrustPolicy Hardening</xhtml:strong>: Setting <xhtml:code>TrustPolicy = 2</xhtml:code> enforces script restriction policies to disallow untrusted or unsigned scripts, providing defense-in-depth even if individual components attempt to execute outside the primary WSH engine.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Defense-in-Depth File Association Remapping</xhtml:strong>: Setting default file associations for legacy script extensions (<xhtml:code>.vbs</xhtml:code>, <xhtml:code>.vbe</xhtml:code>, <xhtml:code>.js</xhtml:code>, <xhtml:code>.jse</xhtml:code>, <xhtml:code>.wsf</xhtml:code>, <xhtml:code>.wsh</xhtml:code>, <xhtml:code>.hta</xhtml:code>) to <xhtml:code>txtfile</xhtml:code> (<xhtml:code>notepad.exe</xhtml:code>) ensures that if a script file is double-clicked in Windows Explorer, it opens harmlessly in Notepad for plain-text inspection rather than executing code.</xhtml:li>
        </xhtml:ol>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:h4>Step 1: Disable WSH via GPO Computer Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Endpoint GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong> for the native 64-bit hive:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong> for <xhtml:code>TrustPolicy</xhtml:code>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a third <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 disablement:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a fourth <xhtml:strong>Registry Item</xhtml:strong> for 32-bit WOW64 TrustPolicy:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 2: Disable WSH in User Configuration Preferences</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a new <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a second <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_CURRENT_USER</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows Script Host\Settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>TrustPolicy</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:h4>Step 3: Remap Script File Extensions to Notepad</xhtml:h4>
        <xhtml:ol>
          <xhtml:li>Navigate to: <xhtml:code>User Configuration\Preferences\Control Panel Settings\Folder Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click and select <xhtml:strong>New -&gt; Open With</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>File Extension</xhtml:em>*: <xhtml:code>vbs</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Associated Program</xhtml:em>*: <xhtml:code>%SystemRoot%\System32\notepad.exe</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Set as default</xhtml:em>*: Check</xhtml:li>
          <xhtml:li>Repeat for the remaining extensions: <xhtml:code>vbe</xhtml:code>, <xhtml:code>js</xhtml:code>, <xhtml:code>jse</xhtml:code>, <xhtml:code>wsf</xhtml:code>, <xhtml:code>wsh</xhtml:code>, and <xhtml:code>hta</xhtml:code>.</xhtml:li>
          <xhtml:li>Alternatively, configure system-wide registry preferences under <xhtml:code>HKLM\SOFTWARE\Classes\.&lt;ext&gt;</xhtml:code> setting the default string value to <xhtml:code>txtfile</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Configure the local registry settings to disable WSH and remap associations.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Disable-Wsh.ps1">Download Script: Disable-Wsh.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Disable-Wsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad.

Write-Host "Applying Windows Script Host and file association hardening..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the WSH configuration state:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-WshStatus.ps1">Download Script: Get-WshStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-WshStatus.ps1
# Description: Audits Windows Script Host registry state across 64-bit and 32-bit hives and script file extension association handlers.

Write-Host "--- Auditing Windows Script Host Hardening ---" -ForegroundColor Cyan

$script:Vulnerable = $false

# 1. Audit WSH Registry settings in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (Test-Path $RegistryHklm) {
    $ValHklm = (Get-ItemProperty -Path $RegistryHklm -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
    if ($ValHklm -eq 0) {
        Write-Host "    - HKLM WSH Enabled: 0 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH is enabled or not configured (Value: '$($ValHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }

    $TrustHklm = (Get-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
    if ($TrustHklm -eq 2) {
        Write-Host "    - HKLM WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
    } else {
        Write-Host "    - VULNERABLE: HKLM WSH TrustPolicy is not set to 2 (Value: '$($TrustHklm)')" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "    - VULNERABLE: HKLM WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
    $script:Vulnerable = $true
}

# 2. Audit WSH Registry settings in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (Test-Path $RegistryWow64) {
        $ValWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
        if ($ValWow64 -eq 0) {
            Write-Host "    - WOW6432Node WSH Enabled: 0 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH is enabled or not configured (Value: '$($ValWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }

        $TrustWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
        if ($TrustWow64 -eq 2) {
            Write-Host "    - WOW6432Node WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: WOW6432Node WSH TrustPolicy is not set to 2 (Value: '$($TrustWow64)')" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: WOW6432Node WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

# 3. Audit file associations
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    if (Test-Path $ProgIdPath) {
        $Handler = (Get-ItemProperty -Path $ProgIdPath -Name "" -ErrorAction SilentlyContinue).""
        if ($Handler -eq "txtfile" -or $Handler -match "notepad") {
            Write-Host "    - Extension .$Ext Handler: $Handler (Secure)" -ForegroundColor Green
        } else {
            Write-Host "    - VULNERABLE: Extension .$Ext Handler is '$($Handler)' (Expected: txtfile/notepad)" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "    - VULNERABLE: Extension .$Ext Class Registry key not found." -ForegroundColor Red
        $script:Vulnerable = $true
    }
}

if ($script:Vulnerable) {
    Write-Host "[-] Audit Result: VULNERABLE - Windows Script Host hardening controls do not meet baseline requirements." -ForegroundColor Red
} else {
    Write-Host "[+] Audit Result: SECURE - Windows Script Host hardening controls are fully compliant." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Disable-Wsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad.

Write-Host "Applying Windows Script Host and file association hardening..." -ForegroundColor Cyan

# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
    New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green

# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
    $RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
    if (-not (Test-Path $RegistryWow64)) {
        New-Item -Path $RegistryWow64 -Force | Out-Null
    }
    Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
    Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
    Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}

# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
    New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green

# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
    $ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
    
    # Update Class Association to Notepad
    if (-not (Test-Path $ProgIdPath)) {
        New-Item -Path $ProgIdPath -Force | Out-Null
    }
    Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
    Write-Host "    Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8034" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-035" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-035] Configure Secure Boot Revocations and Bootloader Updates</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/configure-secure-boot-revocations.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>A vulnerability in the Windows Boot Manager allows an attacker with physical access or local administrative rights to bypass UEFI Secure Boot and execute unsigned code during the boot process (BlackLotus bootkit).</xhtml:p>
        <xhtml:p>To fully mitigate this threat (CVE-2023-24932), Windows update revocations must be applied to the UEFI variables (DBX list) and code integrity SVN policies must be updated. This is managed via the <xhtml:code>AvailableUpdates</xhtml:code> registry key, which instructs the OS boot manager to write the revocation variables to firmware.</xhtml:p>
        <xhtml:p>According to the latest Microsoft guidelines, the recommended trigger value for enterprise deployments to apply all security updates (including the new Windows UEFI CA 2023 certificates and boot manager updates) is <xhtml:strong>`0x5944`</xhtml:strong> (hex) / <xhtml:strong>`22852`</xhtml:strong> (decimal). As the OS processes this bitmask, the value is cleared incrementally, ending up at <xhtml:strong>`0x4000`</xhtml:strong> (hex) / <xhtml:strong>`16384`</xhtml:strong> (decimal) upon successful completion.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To configure the update triggers for the DBX and Code Integrity boot manager revocations, define Registry GPO Preferences inside the endpoints GPO:</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Create a registry item to deploy the <xhtml:code>AvailableUpdates</xhtml:code> DWORD under <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>.</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Secureboot</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AvailableUpdates</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>22852</xhtml:code> (Decimal) or <xhtml:code>5944</xhtml:code> (Hex)</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the BlackLotus mitigation update trigger:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Set-SecureBootRevocations.ps1">Download Script: Set-SecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Set-SecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Audit Script</xhtml:h3>
        <xhtml:p>Run the following script to check the status of Secure Boot revocations on the local machine:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Audit-SecureBootRevocations.ps1">Download Script: Audit-SecureBootRevocations.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Audit-SecureBootRevocations.ps1
# Description: Queries UEFI Secure Boot parameters and audits BlackLotus mitigation registry settings.

Write-Host "--- Auditing BlackLotus Mitigations ---" -ForegroundColor Cyan

$script:NonCompliant = $false

# 1. Audit AvailableUpdates registry key
$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (Test-Path $Path) {
    $Val = Get-ItemProperty -Path $Path -Name "AvailableUpdates" -ErrorAction SilentlyContinue
    $UpdateVal = if ($Val) { $Val.AvailableUpdates } else { 0 }
    
    # Check if configured (&gt;= 0x4000 / 16384)
    if ($UpdateVal -ge 16384) {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Compliant)" -ForegroundColor Green
    } else {
        Write-Host "    - BlackLotus Revocation Updates (AvailableUpdates): $UpdateVal (Non-Compliant - DBX/SVN revocations not triggered)" -ForegroundColor Red
        $script:NonCompliant = $true
    }
} else {
    Write-Host "    - BlackLotus Revocation Updates: Registry path not found (Non-Compliant)" -ForegroundColor Red
    $script:NonCompliant = $true
}

# 2. Audit UEFICA2023Status (if present)
$ServicingPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing"
if (Test-Path $ServicingPath) {
    $ServVal = Get-ItemProperty -Path $ServicingPath -Name "UEFICA2023Status" -ErrorAction SilentlyContinue
    if ($ServVal) {
        $Status = $ServVal.UEFICA2023Status
        $Color = if ($Status -eq "Updated") { "Green" } else { "Yellow" }
        Write-Host "    - UEFI CA 2023 Update Status: $Status" -ForegroundColor $Color
    }
}

if ($script:NonCompliant) {
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Set-SecureBootRevocations.ps1
# Description: Triggers Secure Boot DBX and Code Integrity revocation updates for BlackLotus mitigation.

Write-Host "--- Configuring BlackLotus Secure Boot Mitigations ---" -ForegroundColor Cyan

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Secureboot"
if (-not (Test-Path $Path)) {
    New-Item -Path $Path -Force | Out-Null
}

# Trigger updates (0x5944 = 22852)
Set-ItemProperty -Path $Path -Name "AvailableUpdates" -Value 22852 -Type DWord -Force | Out-Null
Write-Host "[+] BlackLotus DBX and 2023 CA revocation updates configured in registry. A system reboot is required." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8035" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-036" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-036] Enable WDAC Driver Blocklist</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10, Windows 11 (Enterprise and Professional editions)</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-wdac-driver-blocklist.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Attackers frequently employ "Bring Your Own Vulnerable Driver" (BYOVD) attacks to bypass Windows kernel protections on standard endpoints. In a BYOVD attack, an adversary with administrative privileges installs a legitimate, cryptographically signed third-party driver that contains a known, exploitable vulnerability. The attacker then exploits this vulnerability to execute arbitrary code with kernel privileges, allowing them to disable security agents, dump LSASS memory, or tamper with system integrity.</xhtml:p>
        <xhtml:p>Enforcing the <xhtml:strong>Microsoft Vulnerable Driver Blocklist</xhtml:strong> via Windows Defender Application Control (WDAC) prevents known vulnerable or malicious drivers from loading in kernel space. By restricting the WDAC policy to <xhtml:strong>Kernel Mode Code Integrity (KMCI) only</xhtml:strong> (omitting user-mode enforcement), the control shields the system kernel from driver-based exploits on endpoint hosts without introducing administrative overhead or blocking standard user-mode applications.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:p>To enforce the driver blocklist across all endpoints, you can deploy the Microsoft recommended block rules as a custom WDAC policy.</xhtml:p>
        <xhtml:ol>
          <xhtml:li>Download the Microsoft recommended driver block rules XML from the official Microsoft documentation.</xhtml:li>
          <xhtml:li>Edit the XML to ensure it operates in <xhtml:strong>Audit Mode</xhtml:strong> first, then convert the XML configuration into a binary format:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`powershell</xhtml:li>
          <xhtml:li>ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\DriverBlocklist.xml" -BinaryFilePath "C:\WDAC\SIPolicy.p7b"</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Copy the compiled <xhtml:code>SIPolicy.p7b</xhtml:code> file to a secure local path on all target endpoints (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>) or a share.</xhtml:li>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on a domain management host.</xhtml:li>
          <xhtml:li>Create or edit a GPO linked to the workstations OU (e.g., <xhtml:code>GPO_Hardening_Workstations</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Administrative Templates\System\Device Guard</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following setting:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>*: <xhtml:code>Deploy Windows Defender Application Control</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Setting</xhtml:em>*: <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Code Integrity Policy File Path</xhtml:em>*: Enter the local or network path to the policy file (e.g., <xhtml:code>C:\Windows\System32\CodeIntegrity\SIPolicy.p7b</xhtml:code>).</xhtml:li>
          <xhtml:li>To ensure the built-in system driver blocklist is active on modern builds, configure the following registry setting via Group Policy Preferences:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Path</xhtml:em>*: <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\CI\Config</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>VulnerableDriverBlocklistEnable</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
          </xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following scripts locally to enable the Vulnerable Driver Blocklist registry key and ensure proper configuration.</xhtml:p>
        <xhtml:h1>Configure-DriverBlocklist.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-DriverBlocklist.ps1">Download Script: Configure-DriverBlocklist.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
        </xhtml:p>
        <xhtml:h1>Get-DriverBlocklistStatus.ps1</xhtml:h1>
        <xhtml:p>
          <xhtml:a href="audit_scripts/Get-DriverBlocklistStatus.ps1">Download Script: Get-DriverBlocklistStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-DriverBlocklistStatus.ps1
# Description: Audits the configuration of the Microsoft Vulnerable Driver Blocklist and HVCI state.

Write-Host "--- Auditing Vulnerable Driver Blocklist ---" -ForegroundColor Cyan
$Vulnerable = $false

# 1. Check registry value
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (Test-Path $RegPath) {
    $RegValue = Get-ItemProperty -Path $RegPath -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $RegValue -and $RegValue.$ValueName -eq 1) {
        Write-Host "[+] Vulnerable Driver Blocklist is enabled in the registry." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Vulnerable Driver Blocklist is disabled or not set in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Code Integrity Config registry key does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Check HVCI Status
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] VULNERABLE: Memory Integrity (HVCI) is disabled in the registry." -ForegroundColor Red
        $Vulnerable = $true
    }
} else {
    Write-Host "[!] VULNERABLE: Memory Integrity scenario registry path does not exist." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Final Verdict
if ($Vulnerable) {
    Write-Host "`n[!] Verification FAILED: The Vulnerable Driver Blocklist is not fully secured." -ForegroundColor Red
} else {
    Write-Host "`n[+] Verification PASSED: The Vulnerable Driver Blocklist and HVCI are correctly configured." -ForegroundColor Green
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-DriverBlocklist.ps1
# Description: Enables the Microsoft Vulnerable Driver Blocklist in the registry and validates VBS/HVCI settings.

Write-Host "Applying hardening requirement: Enable WDAC Driver Blocklist..." -ForegroundColor Cyan

# 1. Configure the registry settings to enable the blocklist
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config"
$ValueName = "VulnerableDriverBlocklistEnable"

if (-not (Test-Path $RegPath)) {
    Write-Host "[+] Creating registry path: $RegPath" -ForegroundColor Gray
    New-Item -Path $RegPath -Force | Out-Null
}

Write-Host "[+] Setting registry value: $ValueName = 1" -ForegroundColor Gray
Set-ItemProperty -Path $RegPath -Name $ValueName -Value 1 -Type DWord -ErrorAction Stop

# 2. Validate VBS / HVCI Configuration
$ScenariosPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity"
if (Test-Path $ScenariosPath) {
    $HvciStatus = Get-ItemProperty -Path $ScenariosPath -Name "Enabled" -ErrorAction SilentlyContinue
    if ($null -ne $HvciStatus -and $HvciStatus.Enabled -eq 1) {
        Write-Host "[+] Pre-requisite Check: Memory Integrity (HVCI) is enabled." -ForegroundColor Green
    } else {
        Write-Host "[!] Warning: Memory Integrity (HVCI) is disabled. The blocklist requires HVCI for hypervisor enforcement." -ForegroundColor Yellow
    }
} else {
    Write-Host "[!] Warning: Memory Integrity scenario configuration not found. Check VBS settings." -ForegroundColor Yellow
}

Write-Host "[+] Configuration applied successfully. A reboot is required to activate the blocklist." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8036" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-163" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-163] Account Policy: Password Policy for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-password-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Establishing a hardened password baseline across enterprise client workstations and member servers protects against password guessing, automated spray campaigns, and offline cryptanalysis:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Default Domain Policy or target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Password Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce password history</xhtml:em>*: Set to <xhtml:code>24</xhtml:code> passwords remembered</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum password age</xhtml:em>*: Set to <xhtml:code>0</xhtml:code> days (never expire)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minimum password age</xhtml:em>*: Set to <xhtml:code>1</xhtml:code> day</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Minimum password length</xhtml:em>*: Set to <xhtml:code>14</xhtml:code> characters</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Password must meet complexity requirements</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Store passwords using reversible encryption</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Relax minimum password length limits</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Prompt user to change password before expiration</xhtml:em>*: Set to <xhtml:code>14</xhtml:code> days</xhtml:li>
          <xhtml:li>Link the GPO to the target Organizational Units and force replication.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountPasswordPolicy.ps1">Download Script: Configure-EndAccountPasswordPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountPasswordPolicy.ps1
# Description: Configures Endpoint password policy (14 char minimum, relaxed limits, no expiration) via SecEdit.

Write-Host "Configuring Endpoint password policy..." -ForegroundColor Cyan

# 1. Configure PasswordExpiryWarning via Registry
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "PasswordExpiryWarning" -Value 14 -Type DWord -Force

# 2. Configure SecEdit System Access password parameters
$SecTempDir = Join-Path $env:TEMP "EndpointPasswordSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "end_password.cfg"
$DbFile = Join-Path $SecTempDir "end_password.sdb"
$LogFile = Join-Path $SecTempDir "end_password.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[System Access\]") {
    $ConfigText += "`r`n[System Access]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InSystemAccess = $false

$PwdSettings = @{
    "MinimumPasswordLength"        = 14
    "PasswordComplexity"           = 1
    "PasswordHistorySize"          = 24
    "MaxPasswordAge"               = 0
    "MinPasswordAge"               = 1
    "ClearTextPassword"            = 0
    "RelaxMinPasswordLengthLimits" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "System Access") {
            $InSystemAccess = $true
        } else {
            $InSystemAccess = $false
        }
    }
    if ($InSystemAccess) {
        $IsManaged = $false
        foreach ($Key in $PwdSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[System Access]") {
        foreach ($Key in $PwdSettings.Keys) {
            $Val = $PwdSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit password policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Endpoint password policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountPasswordPolicyStatus.ps1">Download Script: Get-EndAccountPasswordPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountPasswordPolicyStatus.ps1
# Description: Audits Endpoint password policy parameters via SecEdit and registry queries.

Write-Host "--- Auditing Endpoint Password Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit Registry Setting
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $WarnVal = (Get-ItemProperty -Path $WinlogonPath -Name "PasswordExpiryWarning" -ErrorAction SilentlyContinue).PasswordExpiryWarning
    if ($null -eq $WarnVal -or $WarnVal -lt 5 -or $WarnVal -gt 14) {
        Write-Host "    [!] VULNERABLE: PasswordExpiryWarning is set to '$WarnVal' (Expected: 5-14)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] PasswordExpiryWarning: $WarnVal (Secure)" -ForegroundColor Green
    }
}

# 2. Audit SecEdit Settings
$SecTempDir = Join-Path $env:TEMP "EndpointPasswordAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "end_password_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "MinimumPasswordLength"        = 14
    "PasswordComplexity"           = 1
    "PasswordHistorySize"          = 24
    "MaxPasswordAge"               = 0
    "MinPasswordAge"               = 1
    "ClearTextPassword"            = 0
    "RelaxMinPasswordLengthLimits" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the active local password policy settings using <xhtml:code>net accounts</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd net accounts </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>Minimum password length</xhtml:code> indicates <xhtml:code>14</xhtml:code>, <xhtml:code>Length of password history maintained</xhtml:code> is <xhtml:code>24</xhtml:code>, and <xhtml:code>Maximum password age (days)</xhtml:code> indicates <xhtml:code>Unlimited</xhtml:code> (value <xhtml:code>0</xhtml:code>).</xhtml:p>
        <xhtml:p>Verify the password expiration warning registry value: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v PasswordExpiryWarning </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>PasswordExpiryWarning</xhtml:code> is set to <xhtml:code>0xe</xhtml:code> (Decimal <xhtml:code>14</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8163" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-164" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-164] Account Policy: Account Lockout Policy for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-lockout-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Configuring a balanced, resilient account lockout baseline across enterprise client workstations and member servers defends against automated password guessing and password spraying while minimizing business interruption from user typos:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Default Domain Policy or the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Account Lockout Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account lockout threshold</xhtml:em>*: Set to <xhtml:code>10</xhtml:code> invalid logon attempts</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Reset account lockout counter after</xhtml:em>*: Set to <xhtml:code>15</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Account lockout duration</xhtml:em>*: Set to <xhtml:code>15</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Administrator account lockout</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Machine account lockout threshold</xhtml:em>*: Set to <xhtml:code>10</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountLockoutPolicy.ps1">Download Script: Configure-EndAccountLockoutPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountLockoutPolicy.ps1
# Description: Configures account lockout parameters and Administrator lockout protection on Endpoints via SecEdit.

Write-Host "Configuring Endpoint account lockout policy..." -ForegroundColor Cyan

# 1. Configure MaxDevicePasswordFailedAttempts via Registry
$SystemPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path $SystemPolicyPath)) {
    New-Item -Path $SystemPolicyPath -Force | Out-Null
}
Set-ItemProperty -Path $SystemPolicyPath -Name "MaxDevicePasswordFailedAttempts" -Value 10 -Type DWord -Force

# 2. Configure SecEdit System Access lockout parameters
$SecTempDir = Join-Path $env:TEMP "EndpointLockoutSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "end_lockout.cfg"
$DbFile = Join-Path $SecTempDir "end_lockout.sdb"
$LogFile = Join-Path $SecTempDir "end_lockout.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[System Access\]") {
    $ConfigText += "`r`n[System Access]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InSystemAccess = $false

$LockoutSettings = @{
    "LockoutBadCount"           = 10
    "ResetLockoutCount"         = 15
    "LockoutDuration"           = 15
    "AllowAdministratorLockout" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "System Access") {
            $InSystemAccess = $true
        } else {
            $InSystemAccess = $false
        }
    }
    if ($InSystemAccess) {
        $IsManaged = $false
        foreach ($Key in $LockoutSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[System Access]") {
        foreach ($Key in $LockoutSettings.Keys) {
            $Val = $LockoutSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit lockout policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Endpoint lockout policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountLockoutPolicyStatus.ps1">Download Script: Get-EndAccountLockoutPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountLockoutPolicyStatus.ps1
# Description: Audits account lockout policy parameters on Endpoints via SecEdit.

Write-Host "--- Auditing Endpoint Account Lockout Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit Registry Setting
$SystemPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$MaxDeviceVal = (Get-ItemProperty -Path $SystemPolicyPath -Name "MaxDevicePasswordFailedAttempts" -ErrorAction SilentlyContinue).MaxDevicePasswordFailedAttempts
if ($null -eq $MaxDeviceVal -or $MaxDeviceVal -gt 10 -or $MaxDeviceVal -eq 0) {
    Write-Host "    [!] VULNERABLE: MaxDevicePasswordFailedAttempts is set to '$MaxDeviceVal' (Expected: 10 or fewer, but not 0)" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    Write-Host "    [+] MaxDevicePasswordFailedAttempts: $MaxDeviceVal (Secure)" -ForegroundColor Green
}

# 2. Audit SecEdit Settings
$SecTempDir = Join-Path $env:TEMP "EndpointLockoutAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "end_lockout_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "LockoutBadCount"           = 10
    "ResetLockoutCount"         = 15
    "LockoutDuration"           = 15
    "AllowAdministratorLockout" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied account lockout policies using <xhtml:code>net accounts</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd net accounts </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>Lockout threshold</xhtml:code> indicates <xhtml:code>10</xhtml:code>, <xhtml:code>Lockout duration (minutes)</xhtml:code> is <xhtml:code>15</xhtml:code>, and <xhtml:code>Lockout observation window (minutes)</xhtml:code> is <xhtml:code>15</xhtml:code>.</xhtml:p>
        <xhtml:p>Verify the machine account lockout threshold registry value: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v MaxDevicePasswordFailedAttempts </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>MaxDevicePasswordFailedAttempts</xhtml:code> returns <xhtml:code>0xa</xhtml:code> (Decimal <xhtml:code>10</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8164" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-165" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-165] Account Policy: Kerberos Policy for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-kerberos-policy.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Kerberos authentication tokens underpin enterprise access across Active Directory environments. Establishing bounded ticket lifetimes and clock synchronization rules restricts ticket reuse, session hijacking, and replay attacks:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit the Default Domain Policy (or target GPO linked to workstations/servers).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Kerberos Policy</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enforce user logon restrictions</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for service ticket</xhtml:em>*: Set to <xhtml:code>600</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket</xhtml:em>*: Set to <xhtml:code>10</xhtml:code> hours</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum lifetime for user ticket renewal</xhtml:em>*: Set to <xhtml:code>7</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Maximum tolerance for computer clock synchronization</xhtml:em>*: Set to <xhtml:code>5</xhtml:code> minutes</xhtml:li>
          <xhtml:li>Link the GPO and force policy application via <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountKerberosPolicy.ps1">Download Script: Configure-EndAccountKerberosPolicy.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountKerberosPolicy.ps1
# Description: Configures Kerberos ticket lifetimes, renewal limits, and client validation on Endpoints via SecEdit.

Write-Host "Configuring Endpoint Kerberos policy..." -ForegroundColor Cyan

$SecTempDir = Join-Path $env:TEMP "EndpointKerberosSecTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}

$CfgFile = Join-Path $SecTempDir "end_kerberos.cfg"
$DbFile = Join-Path $SecTempDir "end_kerberos.sdb"
$LogFile = Join-Path $SecTempDir "end_kerberos.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Throw "Failed to export current security template."
}

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Kerberos Policy\]") {
    $ConfigText += "`r`n[Kerberos Policy]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InKerb = $false

$KerbSettings = @{
    "MaxServiceTicketAge"  = 600
    "MaxTicketAge"         = 10
    "MaxRenewAge"          = 7
    "MaxClockSkew"         = 5
    "TicketValidateClient" = 1
}

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Kerberos Policy") {
            $InKerb = $true
        } else {
            $InKerb = $false
        }
    }
    if ($InKerb) {
        $IsManaged = $false
        foreach ($Key in $KerbSettings.Keys) {
            if ($Line -match "^\s*$($Key)\s*=") {
                $IsManaged = $true
                break
            }
        }
        if (-not $IsManaged) {
            $NewLines += $Line
        }
    } else {
        $NewLines += $Line
    }
}

$FinalLines = @()
foreach ($Line in $NewLines) {
    $FinalLines += $Line
    if ($Line -eq "[Kerberos Policy]") {
        foreach ($Key in $KerbSettings.Keys) {
            $Val = $KerbSettings[$Key]
            $FinalLines += "$($Key) = $($Val)"
        }
    }
}

$FinalLines -join "`r`n" | Out-File -FilePath $CfgFile -Encoding ascii -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas SECURITYPOLICY /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) {
    Throw "Failed to apply SecEdit Kerberos policy."
}

Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Endpoint Kerberos policy applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountKerberosPolicyStatus.ps1">Download Script: Get-EndAccountKerberosPolicyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountKerberosPolicyStatus.ps1
# Description: Audits Kerberos ticket policy parameters on Endpoints via SecEdit.

Write-Host "--- Auditing Endpoint Kerberos Policy ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$SecTempDir = Join-Path $env:TEMP "EndpointKerberosAuditTemplate"
if (-not (Test-Path $SecTempDir)) {
    New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null
}
$CfgFile = Join-Path $SecTempDir "end_kerberos_audit.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigContent = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $SecTempDir -Recurse -Force -ErrorAction SilentlyContinue

$ExpectedSettings = @{
    "MaxServiceTicketAge"  = 600
    "MaxTicketAge"         = 10
    "MaxRenewAge"          = 7
    "MaxClockSkew"         = 5
    "TicketValidateClient" = 1
}

foreach ($Key in $ExpectedSettings.Keys) {
    $Expected = $ExpectedSettings[$Key]
    if ($ConfigContent -match "(?m)^\s*$($Key)\s*=\s*(.*)\s*$") {
        $Actual = $Matches[1].Trim()
    } else {
        $Actual = ""
    }
    if ($Actual -ne [string]$Expected) {
        Write-Host "    [!] VULNERABLE: $($Key) = '$Actual' (Expected: '$Expected')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Key): $Actual (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify current Kerberos tickets on the client using <xhtml:code>klist</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd klist </xhtml:code>
          <xhtml:code /> Verify that active ticket lifetimes conform to the 10-hour boundary.</xhtml:p>
        <xhtml:p>To check local domain time synchronization status: <xhtml:code />
          <xhtml:code>cmd w32tm /query /status </xhtml:code>
          <xhtml:code /> Confirm that the time source is a valid Domain Controller and local clock offset is within acceptable limits (&lt; 1 second).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8165" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-166" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-166] Account Policy: Smart Card Removal Behavior for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-smart-card-removal.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>In enterprise environments deploying physical smart cards, PIV/CAC badges, or FIDO2 cryptographic tokens for endpoint authentication, removing the physical token must immediately transition the host to a secure state. Hardening smart card removal behavior protects against unauthorized physical console access:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Interactive logon: Smart card removal behavior</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and select <xhtml:strong>Lock Workstation</xhtml:strong> (value <xhtml:code>1</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
          </xhtml:li>
          <xhtml:li>Locate the <xhtml:strong>Smart Card Removal Policy</xhtml:strong> service (<xhtml:code>SCPolicySvc</xhtml:code>), set startup to <xhtml:strong>Automatic</xhtml:strong>, and start the service.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountSmartCardRemoval.ps1">Download Script: Configure-EndAccountSmartCardRemoval.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountSmartCardRemoval.ps1
# Description: Configures Smart Card removal behavior to Lock Workstation and enables SCPolicySvc on Endpoints.

Write-Host "Configuring Endpoint Smart Card removal behavior..." -ForegroundColor Cyan

# 1. Configure Winlogon ScRemoveOption
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "ScRemoveOption" -Value "1" -Type String -Force

# 2. Ensure Smart Card Removal Policy service is configured for Automatic start
$ServiceName = "SCPolicySvc"
$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    Set-Service -Name $ServiceName -StartupType Automatic
    if ($Service.Status -ne "Running") {
        Start-Service -Name $ServiceName -ErrorAction SilentlyContinue
    }
}

Write-Host "Smart card removal behavior set to Lock Workstation ('1') and service configured." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountSmartCardRemovalStatus.ps1">Download Script: Get-EndAccountSmartCardRemovalStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountSmartCardRemovalStatus.ps1
# Description: Audits Smart Card removal behavior and service status on Endpoints.

Write-Host "--- Auditing Endpoint Smart Card Removal Behavior ---" -ForegroundColor Cyan

$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"

if (-not (Test-Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $WinlogonPath -Name "ScRemoveOption" -ErrorAction SilentlyContinue).ScRemoveOption

if ($Val -eq "1") {
    Write-Host "    [+] ScRemoveOption is set to '$Val' (Lock Workstation - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: ScRemoveOption is set to '$Val' (Expected: '1')" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry setting via command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v ScRemoveOption </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>ScRemoveOption</xhtml:code> is <xhtml:code>REG_SZ</xhtml:code> with value <xhtml:code>"1"</xhtml:code>.</xhtml:p>
        <xhtml:p>Verify the Smart Card Removal Policy service state: <xhtml:code />
          <xhtml:code>cmd sc query SCPolicySvc </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>STATE</xhtml:code> is <xhtml:code>RUNNING</xhtml:code> and <xhtml:code>START_TYPE</xhtml:code> is <xhtml:code>AUTO_START</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8166" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-167" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-167] Account Policy: Cached Logons and PBKDF2 Iteration Count for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-cached-logons.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>When domain users authenticate against Windows workstations, the operating system can cache authentication verifiers locally to permit subsequent logons if an Active Directory Domain Controller is unreachable. Hardening this mechanism limits local credential exposure and renders offline attacks computationally unfeasible:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints_Desktops</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Interactive logon: Number of previous logons to cache (in case domain controller is not available)</xhtml:strong>.</xhtml:li>
          <xhtml:li>Check <xhtml:strong>Define this policy setting</xhtml:strong> and set the cache value to <xhtml:strong>0</xhtml:strong> logons (or <xhtml:code>2</xhtml:code> for a dedicated roaming laptops OU).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SECURITY\Cache</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>NL$IterationCount</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>1954</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountCachedLogons.ps1">Download Script: Configure-EndAccountCachedLogons.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountCachedLogons.ps1
# Description: Disables cached domain logons and fortifies PBKDF2 iteration count on Endpoints.

Write-Host "Configuring Endpoint cached logon restrictions and PBKDF2 iterations..." -ForegroundColor Cyan

# 1. Disable cached logons count
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    New-Item -Path $WinlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $WinlogonPath -Name "CachedLogonsCount" -Value 0 -Type DWord -Force

# 2. Configure PBKDF2 Iteration Count
$CachePath = "HKLM:\SECURITY\Cache"
if (-not (Test-Path $CachePath)) {
    New-Item -Path $CachePath -Force | Out-Null
}
Set-ItemProperty -Path $CachePath -Name "NL`$IterationCount" -Value 1954 -Type DWord -Force

Write-Host "Cached logons count disabled (0) and PBKDF2 iteration count configured (1954)." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountCachedLogonsStatus.ps1">Download Script: Get-EndAccountCachedLogonsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountCachedLogonsStatus.ps1
# Description: Audits cached logons count and PBKDF2 iteration count on Endpoints.

Write-Host "--- Auditing Endpoint Cached Logons and PBKDF2 Settings ---" -ForegroundColor Cyan
$script:Vulnerable = $false

# 1. Audit CachedLogonsCount
$WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
if (-not (Test-Path $WinlogonPath)) {
    Write-Host "    [!] MISSING KEY: $WinlogonPath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $CacheCount = (Get-ItemProperty -Path $WinlogonPath -Name "CachedLogonsCount" -ErrorAction SilentlyContinue).CachedLogonsCount
    if ($CacheCount -ne 0) {
        Write-Host "    [!] VULNERABLE: CachedLogonsCount is '$CacheCount' (Expected: 0)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] CachedLogonsCount: 0 (Secure - Cache Disabled)" -ForegroundColor Green
    }
}

# 2. Audit NL$IterationCount
$CachePath = "HKLM:\SECURITY\Cache"
if (-not (Test-Path $CachePath)) {
    Write-Host "    [!] MISSING KEY: $CachePath" -ForegroundColor Red
    $script:Vulnerable = $true
} else {
    $IterCount = (Get-ItemProperty -Path $CachePath -Name "NL`$IterationCount" -ErrorAction SilentlyContinue)."NL`$IterationCount"
    if ($IterCount -ne 1954) {
        Write-Host "    [!] VULNERABLE: NL`$IterationCount is '$IterCount' (Expected: 1954)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] NL`$IterationCount: 1954 (Secure - ~2M PBKDF2 Iterations)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry configuration using command line queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v CachedLogonsCount </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>CachedLogonsCount</xhtml:code> returns <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:p>To inspect the <xhtml:code>SECURITY\Cache</xhtml:code> key (using elevated command prompt via <xhtml:code>psexec -s cmd.exe</xhtml:code>): <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SECURITY\Cache" /v NL$IterationCount </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>NL$IterationCount</xhtml:code> returns <xhtml:code>0x7a2</xhtml:code> (Decimal <xhtml:code>1954</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8167" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-168" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-168] Account Policy: Local Accounts and Blank Password Restrictions for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-local-blank-passwords.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Local accounts represent an attractive target for initial access and lateral movement across enterprise workstations. Restricting blank password usage, purging insecure LAN Manager hashes, and enforcing the Classic network authentication model hardens the local SAM perimeter across endpoints:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Accounts: Limit local account use of blank passwords to console logon only</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Do not store LAN Manager hash value on next password change</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Sharing and security model for local accounts</xhtml:em>*: Set to <xhtml:code>Classic - local users authenticate as themselves</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and member server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountLocalBlankPasswords.ps1">Download Script: Configure-EndAccountLocalBlankPasswords.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountLocalBlankPasswords.ps1
# Description: Enforces blank password restrictions, purges LM hashes, and sets Classic sharing on Endpoints.

Write-Host "Configuring Endpoint local account and blank password restrictions..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path -Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}

Set-ItemProperty -Path $LsaPath -Name "LimitBlankPasswordUse" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "NoLMHash" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "ForceNetworkLogon" -Value 0 -Type DWord -Force

Write-Host "Local account and blank password restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountLocalBlankPasswordsStatus.ps1">Download Script: Get-EndAccountLocalBlankPasswordsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountLocalBlankPasswordsStatus.ps1
# Description: Audits local account restrictions, LM hash generation, and sharing model on Endpoints.

Write-Host "--- Auditing Endpoint Local Account and Blank Password Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"

function Test-RegVal ($Name, $Expected) {
    if (-not (Test-Path -Path $LsaPath)) {
        Write-Host "    [!] MISSING KEY: $LsaPath" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $LsaPath -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $LsaPath (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "LimitBlankPasswordUse" 1
Test-RegVal "NoLMHash" 1
Test-RegVal "ForceNetworkLogon" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v NoLMHash reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v ForceNetworkLogon </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>LimitBlankPasswordUse</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>NoLMHash</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>ForceNetworkLogon</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8168" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-169" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-169] Account Policy: NTLM and LAN Manager Authentication Security for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-ntlm-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Legacy authentication protocols such as LAN Manager (LM) and NTLMv1 represent major vectors for credential interception, offline password recovery, and adversary-in-the-middle relay attacks across corporate networks. Hardening NTLM authentication parameters across endpoints enforces modern cryptographic session controls:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: LAN Manager authentication level</xhtml:em>*: Set to <xhtml:code>Send NTLMv2 response only. Refuse LM &amp; NTLM</xhtml:code> (value <xhtml:code>5</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Minimum session security for NTLM SSP based (including secure RPC) clients</xhtml:em>*: Check both <xhtml:code>Require NTLMv2 session security</xhtml:code> and <xhtml:code>Require 128-bit encryption</xhtml:code> (value <xhtml:code>537395200</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Minimum session security for NTLM SSP based (including secure RPC) servers</xhtml:em>*: Check both <xhtml:code>Require NTLMv2 session security</xhtml:code> and <xhtml:code>Require 128-bit encryption</xhtml:code> (value <xhtml:code>537395200</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Allow LocalSystem NULL session fallback</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and member server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountNtlmSecurity.ps1">Download Script: Configure-EndAccountNtlmSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountNtlmSecurity.ps1
# Description: Enforces NTLMv2-only authentication, 128-bit session security, and blocks NULL session fallback on Endpoints.

Write-Host "Configuring Endpoint NTLM and LAN Manager authentication security..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "LmCompatibilityLevel" -Value 5 -Type DWord -Force

$MsvPath = "HKLM:\System\CurrentControlSet\Control\Lsa\MSV1_0"
if (-not (Test-Path $MsvPath)) {
    New-Item -Path $MsvPath -Force | Out-Null
}
Set-ItemProperty -Path $MsvPath -Name "NTLMMinClientSec" -Value 537395200 -Type DWord -Force
Set-ItemProperty -Path $MsvPath -Name "NTLMMinServerSec" -Value 537395200 -Type DWord -Force
Set-ItemProperty -Path $MsvPath -Name "allownullsessionfallback" -Value 0 -Type DWord -Force

Write-Host "NTLM and LAN Manager authentication security applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountNtlmSecurityStatus.ps1">Download Script: Get-EndAccountNtlmSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountNtlmSecurityStatus.ps1
# Description: Audits NTLM authentication levels, session security, and NULL session fallback on Endpoints.

Write-Host "--- Auditing Endpoint NTLM and LAN Manager Security ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$MsvPath = "HKLM:\System\CurrentControlSet\Control\Lsa\MSV1_0"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $LsaPath "LmCompatibilityLevel" 5
Test-RegVal $MsvPath "NTLMMinClientSec" 537395200
Test-RegVal $MsvPath "NTLMMinServerSec" 537395200
Test-RegVal $MsvPath "allownullsessionfallback" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied NTLM settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v LmCompatibilityLevel reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v NTLMMinClientSec reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v NTLMMinServerSec reg query "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0" /v allownullsessionfallback </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>LmCompatibilityLevel</xhtml:code> is <xhtml:code>0x5</xhtml:code>, <xhtml:code>NTLMMinClientSec</xhtml:code> and <xhtml:code>NTLMMinServerSec</xhtml:code> are <xhtml:code>0x20080000</xhtml:code> (Decimal <xhtml:code>537395200</xhtml:code>), and <xhtml:code>allownullsessionfallback</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8169" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-170" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-170] Account Policy: Disable WDigest Credential Caching for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-wdigest-credentials.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (LSASS) holds authentication tokens and session security contexts for logged-on users. Historically, the WDigest provider retained cleartext passwords in memory, exposing enterprise networks to devastating credential theft:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Preferences\Windows Settings\Registry</xhtml:code>
          </xhtml:li>
          <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong>, select <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value name</xhtml:em>*: <xhtml:code>UseLogonCredential</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Value data</xhtml:em>*: <xhtml:code>0</xhtml:code> (Decimal)</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and member server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountWdigestCredentials.ps1">Download Script: Configure-EndAccountWdigestCredentials.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountWdigestCredentials.ps1
# Description: Disables WDigest plaintext credential caching in LSASS memory on Endpoints.

Write-Host "Disabling WDigest plaintext credential caching on Endpoints..." -ForegroundColor Cyan

$WDigestPath = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\WDigest"
if (-not (Test-Path $WDigestPath)) {
    New-Item -Path $WDigestPath -Force | Out-Null
}
Set-ItemProperty -Path $WDigestPath -Name "UseLogonCredential" -Value 0 -Type DWord -Force

Write-Host "WDigest credential caching disabled successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountWdigestCredentialsStatus.ps1">Download Script: Get-EndAccountWdigestCredentialsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountWdigestCredentialsStatus.ps1
# Description: Audits WDigest plaintext credential caching status on Endpoints.

Write-Host "--- Auditing Endpoint WDigest Credential Caching ---" -ForegroundColor Cyan

$WDigestPath = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\WDigest"

if (-not (Test-Path $WDigestPath)) {
    Write-Host "    [!] MISSING KEY: $WDigestPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $WDigestPath -Name "UseLogonCredential" -ErrorAction SilentlyContinue).UseLogonCredential

if ($null -ne $Val -and $Val -eq 0) {
    Write-Host "    [+] UseLogonCredential is set to 0 (Disabled - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: UseLogonCredential is '$Val' (Expected: 0)" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied WDigest setting via command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\SecurityProviders\WDigest" /v UseLogonCredential </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>UseLogonCredential</xhtml:code> is of type <xhtml:code>REG_DWORD</xhtml:code> with value <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8170" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-171" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-171] Account Policy: Windows Hello for Business and PIN Complexity for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-hello-pin.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Deploying Windows Hello for Business (WHfB) across enterprise workstations transitions the environment from vulnerable password-based authentication to hardware-bound asymmetric cryptographic keys. However, strict policy constraints must be enforced to prevent weak PIN choices and insecure fallback mechanisms:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure System Logon policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Logon</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Turn on convenience PIN sign-in</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Configure PIN Complexity policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\PIN Complexity</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Minimum PIN length</xhtml:em>
            <xhtml:em>, set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*, and enter <xhtml:code>6</xhtml:code>.</xhtml:li>
          <xhtml:li>Configure Windows Hello for Business policies:</xhtml:li>
          <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Hello for Business</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Use a hardware security device</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Use convenience PIN sign-in</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Double-click </xhtml:em>
            <xhtml:em>Allow Microsoft accounts to be optional</xhtml:em>
            <xhtml:em> and set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountHelloPin.ps1">Download Script: Configure-EndAccountHelloPin.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountHelloPin.ps1
# Description: Hardens Windows Hello for Business, disables convenience PINs, and mandates TPM hardware backing on Endpoints.

Write-Host "Configuring Endpoint Windows Hello for Business and PIN policies..." -ForegroundColor Cyan

# 1. System Logon PIN Policy
$SysPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $SysPath)) {
    New-Item -Path $SysPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPath -Name "AllowDomainPINLogon" -Value 0 -Type DWord -Force

# 2. PIN Complexity
$PinPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity"
if (-not (Test-Path $PinPath)) {
    New-Item -Path $PinPath -Force | Out-Null
}
Set-ItemProperty -Path $PinPath -Name "MinimumPINLength" -Value 6 -Type DWord -Force

# 3. Hardware Security Device
$PfwPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork"
if (-not (Test-Path $PfwPath)) {
    New-Item -Path $PfwPath -Force | Out-Null
}
Set-ItemProperty -Path $PfwPath -Name "RequireSecurityDevice" -Value 1 -Type DWord -Force

$TpmPath = "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\ExcludeSecurityDevices"
if (-not (Test-Path $TpmPath)) {
    New-Item -Path $TpmPath -Force | Out-Null
}
Set-ItemProperty -Path $TpmPath -Name "TPM12" -Value 0 -Type DWord -Force

# 4. MSA Optional
$SysPolPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path $SysPolPath)) {
    New-Item -Path $SysPolPath -Force | Out-Null
}
Set-ItemProperty -Path $SysPolPath -Name "MSAOptional" -Value 1 -Type DWord -Force

Write-Host "Windows Hello and PIN policies applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountHelloPinStatus.ps1">Download Script: Get-EndAccountHelloPinStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountHelloPinStatus.ps1
# Description: Audits Windows Hello for Business, PIN complexity, and TPM enforcement status on Endpoints.

Write-Host "--- Auditing Endpoint Windows Hello and PIN Policies ---" -ForegroundColor Cyan
$script:Vulnerable = $false

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" "AllowDomainPINLogon" 0
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity" "MinimumPINLength" 6
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork" "RequireSecurityDevice" 1
Test-RegVal "HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\ExcludeSecurityDevices" "TPM12" 0
Test-RegVal "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "MSAOptional" 1

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policies using command line queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v AllowDomainPINLogon reg query "HKLM\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity" /v MinimumPINLength reg query "HKLM\SOFTWARE\Policies\Microsoft\PassportForWork" /v RequireSecurityDevice reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v MSAOptional </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>AllowDomainPINLogon</xhtml:code> is <xhtml:code>0x0</xhtml:code>, <xhtml:code>MinimumPINLength</xhtml:code> is <xhtml:code>0x6</xhtml:code>, <xhtml:code>RequireSecurityDevice</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>MSAOptional</xhtml:code> is <xhtml:code>0x1</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8171" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-172" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-172] Account Policy: Consumer Microsoft Account Restrictions for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-block-msa.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Allowing users to attach consumer Microsoft Accounts (such as <xhtml:code>@outlook.com</xhtml:code>, <xhtml:code>@hotmail.com</xhtml:code>, or <xhtml:code>@live.com</xhtml:code>) to enterprise-managed client workstations bypasses corporate identity perimeters and exposes organizational data to unauthorized external storage:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Microsoft Account</xhtml:code>
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Block all consumer Microsoft account user authentication</xhtml:strong>.</xhtml:li>
          <xhtml:li>Set the policy to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the target workstation Organizational Units (OUs).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountBlockMsa.ps1">Download Script: Configure-EndAccountBlockMsa.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountBlockMsa.ps1
# Description: Blocks consumer Microsoft account user authentication on Endpoints.

Write-Host "Blocking consumer Microsoft account user authentication on Endpoints..." -ForegroundColor Cyan

$MsaPath = "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftAccount"
if (-not (Test-Path -Path $MsaPath)) {
    New-Item -Path $MsaPath -Force | Out-Null
}
Set-ItemProperty -Path $MsaPath -Name "DisableUserAuth" -Value 1 -Type DWord -Force

Write-Host "Consumer Microsoft account user authentication blocked successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountBlockMsaStatus.ps1">Download Script: Get-EndAccountBlockMsaStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountBlockMsaStatus.ps1
# Description: Audits consumer Microsoft account blocking status on Endpoints.

Write-Host "--- Auditing Endpoint Consumer Microsoft Account Restrictions ---" -ForegroundColor Cyan

$MsaPath = "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftAccount"

if (-not (Test-Path -Path $MsaPath)) {
    Write-Host "    [!] MISSING KEY: $MsaPath" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}

$Val = (Get-ItemProperty -Path $MsaPath -Name "DisableUserAuth" -ErrorAction SilentlyContinue).DisableUserAuth

if ($null -ne $Val -and $Val -eq 1) {
    Write-Host "    [+] DisableUserAuth is set to 1 (Enabled - Secure)." -ForegroundColor Green
    Write-Output "Compliant"
    exit 0
} else {
    Write-Host "    [!] VULNERABLE: DisableUserAuth is '$Val' (Expected: 1)" -ForegroundColor Red
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy via command prompt using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftAccount" /v DisableUserAuth </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>DisableUserAuth</xhtml:code> exists with a value of <xhtml:code>0x1</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8172" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-173" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-173] Account Policy: Domain Member Secure Channel Security for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-secure-channel.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Netlogon secure channel provides the core trust link between enterprise workstations, member servers, and Active Directory Domain Controllers for user authentication, group enumeration, and secure channel key rotation. Hardening this channel prevents cryptographic downgrade, spoofing, and machine account persistence:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally encrypt or sign secure channel data (always)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally encrypt secure channel data (when possible)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Digitally sign secure channel data (when possible)</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Disable machine account password changes</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Maximum machine account password age</xhtml:em>*: Set to <xhtml:code>30</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Domain member: Require strong (Windows 2000 or later) session key</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and member server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountSecureChannel.ps1">Download Script: Configure-EndAccountSecureChannel.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountSecureChannel.ps1
# Description: Configures Netlogon secure channel signing, sealing, strong keys, and password rotation on Endpoints.

Write-Host "Configuring Endpoint Domain Member Secure Channel settings..." -ForegroundColor Cyan

$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path -Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}

Set-ItemProperty -Path $NetlogonPath -Name "RequireSignOrSeal" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "SealSecureChannel" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "SignSecureChannel" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "DisablePasswordChange" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "MaximumPasswordAge" -Value 30 -Type DWord -Force
Set-ItemProperty -Path $NetlogonPath -Name "RequireStrongKey" -Value 1 -Type DWord -Force

Write-Host "Domain Member Secure Channel settings applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountSecureChannelStatus.ps1">Download Script: Get-EndAccountSecureChannelStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountSecureChannelStatus.ps1
# Description: Audits Netlogon secure channel parameters on Endpoints.

Write-Host "--- Auditing Endpoint Domain Member Secure Channel Settings ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $NetlogonPath "RequireSignOrSeal" 1
Test-RegVal $NetlogonPath "SealSecureChannel" 1
Test-RegVal $NetlogonPath "SignSecureChannel" 1
Test-RegVal $NetlogonPath "DisablePasswordChange" 0
Test-RegVal $NetlogonPath "MaximumPasswordAge" 30
Test-RegVal $NetlogonPath "RequireStrongKey" 1

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the active secure channel trust relationship using <xhtml:code>nltest</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd nltest /sc_query:%USERDNSDOMAIN% nltest /sc_verify:%USERDNSDOMAIN% </xhtml:code>
          <xhtml:code /> Confirm that the status returns <xhtml:code>NTRR_SUCCESS</xhtml:code> (or <xhtml:code>0x0</xhtml:code>).</xhtml:p>
        <xhtml:p>Verify the applied registry configuration using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v RequireSignOrSeal reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v RequireStrongKey reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v MaximumPasswordAge </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>RequireSignOrSeal</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>RequireStrongKey</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>MaximumPasswordAge</xhtml:code> is <xhtml:code>0x1e</xhtml:code> (Decimal <xhtml:code>30</xhtml:code>).</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8173" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-174" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-174] Account Policy: SMB Client and Server Security Options for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-smb-security.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Server Message Block (SMB) protocol is integral to enterprise file sharing, administrative automation, and printer sharing. Hardening SMB client and server parameters protects against cleartext credential theft, resource exhaustion from dormant sessions, and anonymous file access:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network client: Send unencrypted password to third-party SMB servers</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Amount of idle time required before suspending session</xhtml:em>*: Set to <xhtml:code>15</xhtml:code> minutes</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Microsoft network server: Disconnect clients when logon hours expire</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Force logoff when logon hours expire</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Shares that can be accessed anonymously</xhtml:em>*: Set to <xhtml:code>None</xhtml:code> (leave field completely empty)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and member server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountSmbSecurity.ps1">Download Script: Configure-EndAccountSmbSecurity.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountSmbSecurity.ps1
# Description: Configures SMB client and server security options (plaintext block, auto-disconnect, logon hours) on Endpoints.

Write-Host "Configuring Endpoint SMB client and server security options..." -ForegroundColor Cyan

# 1. LanmanWorkstation: Block plaintext passwords
$WorkstationPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
if (-not (Test-Path -Path $WorkstationPath)) {
    New-Item -Path $WorkstationPath -Force | Out-Null
}
Set-ItemProperty -Path $WorkstationPath -Name "EnablePlainTextPassword" -Value 0 -Type DWord -Force

# 2. LanmanServer: AutoDisconnect, EnableForcedLogoff, NullSessionShares
$ServerPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
if (-not (Test-Path -Path $ServerPath)) {
    New-Item -Path $ServerPath -Force | Out-Null
}
Set-ItemProperty -Path $ServerPath -Name "AutoDisconnect" -Value 15 -Type DWord -Force
Set-ItemProperty -Path $ServerPath -Name "EnableForcedLogoff" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ServerPath -Name "NullSessionShares" -Value @() -Type MultiString -Force

# 3. Netlogon: ForceLogoffWhenHourExpire
$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"
if (-not (Test-Path -Path $NetlogonPath)) {
    New-Item -Path $NetlogonPath -Force | Out-Null
}
Set-ItemProperty -Path $NetlogonPath -Name "ForceLogoffWhenHourExpire" -Value 1 -Type DWord -Force

Write-Host "SMB client and server security options applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountSmbSecurityStatus.ps1">Download Script: Get-EndAccountSmbSecurityStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountSmbSecurityStatus.ps1
# Description: Audits SMB client and server security options on Endpoints.

Write-Host "--- Auditing Endpoint SMB Client and Server Security Options ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$WorkstationPath = "HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters"
$ServerPath = "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters"
$NetlogonPath = "HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $WorkstationPath "EnablePlainTextPassword" 0
Test-RegVal $ServerPath "AutoDisconnect" 15
Test-RegVal $ServerPath "EnableForcedLogoff" 1
Test-RegVal $NetlogonPath "ForceLogoffWhenHourExpire" 1

# Audit NullSessionShares
if (Test-Path -Path $ServerPath) {
    $NullShares = (Get-ItemProperty -Path $ServerPath -Name "NullSessionShares" -ErrorAction SilentlyContinue).NullSessionShares
    if ($null -ne $NullShares -and $NullShares.Count -gt 0 -and ($NullShares -join "") -ne "") {
        Write-Host "    [!] VULNERABLE: NullSessionShares contains: $($NullShares -join ', ')" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] NullSessionShares: Empty (Secure)" -ForegroundColor Green
    }
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied SMB settings using command prompt queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v EnablePlainTextPassword reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v AutoDisconnect reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v EnableForcedLogoff reg query "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v ForceLogoffWhenHourExpire reg query "HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters" /v NullSessionShares </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>EnablePlainTextPassword</xhtml:code> is <xhtml:code>0x0</xhtml:code>, <xhtml:code>AutoDisconnect</xhtml:code> is <xhtml:code>0xf</xhtml:code> (Decimal <xhtml:code>15</xhtml:code>), <xhtml:code>EnableForcedLogoff</xhtml:code> is <xhtml:code>0x1</xhtml:code>, <xhtml:code>ForceLogoffWhenHourExpire</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>NullSessionShares</xhtml:code> is empty.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8174" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-175" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-175] Account Policy: Anonymous Access and Enumeration Restrictions for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-anonymous-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Restricting unauthenticated network reconnaissance protects local SAM databases, user account identifiers, and shared directory paths across enterprise endpoints and member servers:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Do not allow anonymous enumeration of SAM accounts</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Do not allow anonymous enumeration of SAM accounts and shares</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network access: Allow anonymous SID/Name translation</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Network security: Allow PKU2U authentication requests to this computer to use online identities</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>System objects: Require case insensitivity for non-Windows subsystems</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and server Organizational Units (OUs).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountAnonymousRestrictions.ps1">Download Script: Configure-EndAccountAnonymousRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountAnonymousRestrictions.ps1
# Description: Hardens anonymous access, SAM enumeration, PKU2U, and subsystem object naming on Endpoints.

Write-Host "Configuring Endpoint anonymous access and enumeration restrictions..." -ForegroundColor Cyan

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
if (-not (Test-Path -Path $LsaPath)) {
    New-Item -Path $LsaPath -Force | Out-Null
}
Set-ItemProperty -Path $LsaPath -Name "RestrictAnonymousSAM" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "RestrictAnonymous" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $LsaPath -Name "ObaseCaseInsensitive" -Value 1 -Type DWord -Force

$KerbPath = "HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters"
if (-not (Test-Path $KerbPath)) {
    New-Item -Path $KerbPath -Force | Out-Null
}
Set-ItemProperty -Path $KerbPath -Name "AllowPKU2U" -Value 0 -Type DWord -Force

Write-Host "Anonymous access and enumeration restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountAnonymousRestrictionsStatus.ps1">Download Script: Get-EndAccountAnonymousRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountAnonymousRestrictionsStatus.ps1
# Description: Audits Endpoint anonymous enumeration, PKU2U, and subsystem object security configuration.

Write-Host "--- Auditing Endpoint Anonymous Access and Enumeration Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$LsaPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$KerbPath = "HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters"

function Test-RegVal ($Path, $Name, $Expected) {
    if (-not (Test-Path -Path $Path)) {
        Write-Host "    [!] MISSING KEY: $Path" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $Path (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name under $Path is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal $LsaPath "RestrictAnonymousSAM" 1
Test-RegVal $LsaPath "RestrictAnonymous" 1
Test-RegVal $LsaPath "ObaseCaseInsensitive" 1
Test-RegVal $KerbPath "AllowPKU2U" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry settings using <xhtml:code>reg query</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymousSAM reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v ObaseCaseInsensitive reg query "HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters" /v AllowPKU2U </xhtml:code>
          <xhtml:code /> Confirm that each key exists and the values match: <xhtml:code>RestrictAnonymousSAM</xhtml:code> = <xhtml:code>0x1</xhtml:code>, <xhtml:code>RestrictAnonymous</xhtml:code> = <xhtml:code>0x1</xhtml:code>, <xhtml:code>ObaseCaseInsensitive</xhtml:code> = <xhtml:code>0x1</xhtml:code>, and <xhtml:code>AllowPKU2U</xhtml:code> = <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8175" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-176" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-176] Account Policy: Interactive Logon Security Options for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Professional (all builds), Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/account-policy/configure-end-account-interactive-logon.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Interactive logon configurations govern how users authenticate at the physical console or remote desktop interface. Hardening these parameters across client endpoints and member servers defends against credential phishing, shoulder surfing, and intentional system crash exploits:</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Do not require CTRL+ALT+DEL</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Interactive logon: Don't display last signed-in</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code> (value <xhtml:code>1</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Audit: Shut down system immediately if unable to log security audits</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code> (value <xhtml:code>0</xhtml:code>)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate workstation and server Organizational Units.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAccountInteractiveLogon.ps1">Download Script: Configure-EndAccountInteractiveLogon.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndAccountInteractiveLogon.ps1
# Description: Configures interactive logon security options (SAS requirement, hide last user, audit stability) on Endpoints.

Write-Host "Configuring Endpoint interactive logon security options..." -ForegroundColor Cyan

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if (-not (Test-Path -Path $SystemPath)) {
    New-Item -Path $SystemPath -Force | Out-Null
}

Set-ItemProperty -Path $SystemPath -Name "DisableCAD" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $SystemPath -Name "DontDisplayLastUserName" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $SystemPath -Name "CrashOnAuditFail" -Value 0 -Type DWord -Force

Write-Host "Interactive logon security options applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To audit the hardening status:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAccountInteractiveLogonStatus.ps1">Download Script: Get-EndAccountInteractiveLogonStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndAccountInteractiveLogonStatus.ps1
# Description: Audits interactive logon security options on Endpoints.

Write-Host "--- Auditing Endpoint Interactive Logon Security Options ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$SystemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

function Test-RegVal ($Name, $Expected) {
    if (-not (Test-Path -Path $SystemPath)) {
        Write-Host "    [!] MISSING KEY: $SystemPath" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Prop = Get-ItemProperty -Path $SystemPath -Name $Name -ErrorAction SilentlyContinue
    if ($null -eq $Prop -or $null -eq $Prop.$Name) {
        Write-Host "    [!] MISSING VALUE: $Name under $SystemPath (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
        return
    }
    $Val = $Prop.$Name
    if ($Val -ne $Expected) {
        Write-Host "    [!] VULNERABLE: $Name is '$Val' (Expected: $Expected)" -ForegroundColor Red
        $script:Vulnerable = $true
    } else {
        Write-Host "    [+] $($Name): $Val (Secure)" -ForegroundColor Green
    }
}

Test-RegVal "DisableCAD" 0
Test-RegVal "DontDisplayLastUserName" 1
Test-RegVal "CrashOnAuditFail" 0

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied registry configuration using command line queries: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DisableCAD reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DontDisplayLastUserName reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v CrashOnAuditFail </xhtml:code>
          <xhtml:code /> Confirm that <xhtml:code>DisableCAD</xhtml:code> is <xhtml:code>0x0</xhtml:code>, <xhtml:code>DontDisplayLastUserName</xhtml:code> is <xhtml:code>0x1</xhtml:code>, and <xhtml:code>CrashOnAuditFail</xhtml:code> is <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8176" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-178" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-178] Enable Kerberos Armoring for Endpoints</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10, Windows 11</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/enable-kerberos-armoring.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Active Directory environments relying on standard Kerberos authentication are susceptible to offline brute-force, dictionary attacks, and credential harvesting. During standard Kerberos pre-authentication, the client sends an Authentication Service Request (AS-REQ) containing timestamp data encrypted with the user's password hash. Attackers monitoring network traffic can intercept these timestamps, or execute AS-REP roasting against accounts that do not require Kerberos pre-authentication (<xhtml:code>DONT_REQ_PREAUTH</xhtml:code>), conducting offline hash cracking to recover cleartext credentials.</xhtml:p>
        <xhtml:p>Kerberos Armoring, also known as Flexible Authentication Secure Tunneling (FAST - RFC 6113), mitigates this vulnerability by establishing an encrypted channel between the client workstation and the Key Distribution Center (KDC) on the Domain Controller. This tunnel is encrypted using the computer account's credential (or machine certificate), protecting pre-authentication messages (AS-REQ and AS-REP) from eavesdropping, offline dictionary attacks, and message tampering.</xhtml:p>
        <xhtml:p>On standard Tier 2 client workstations, Kerberos Armoring is configured for opportunistic negotiation (<xhtml:code>RequireFast = 0</xhtml:code>). This instructs the Windows Kerberos security provider to request armored exchanges whenever communicating with FAST-capable Domain Controllers, while maintaining backward compatibility with legacy resource servers, external forest trusts, and non-Windows Kerberos realms that do not yet support RFC 6113 FAST.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>) on an administrative workstation.</xhtml:li>
          <xhtml:li>Edit the workstation hardening GPO applied to standard clients (e.g., <xhtml:code>GPO_Hardening_Workstations_Tier2</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Kerberos</xhtml:code>
          </xhtml:li>
          <xhtml:li>Configure the following settings:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Kerberos client support for claims, compound authentication and Kerberos armoring` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>
            <xhtml:em />
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Support device authentication using certificate` -&gt; </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>* (Select <xhtml:code>Automatic</xhtml:code> in options)</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Policy</xhtml:em>
            <xhtml:em>: `Fail authentication requests when Kerberos armoring is not available` -&gt; </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>* (or Not Configured)</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Tier 2 Workstations Organizational Units (OUs).</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Use this method to apply the setting locally (for testing, non-domain scenarios, or standalone client deployment) or if the control is not manageable via standard GPO interfaces.</xhtml:p>
        <xhtml:p>
          <xhtml:a href="implementation_scripts/Configure-EndKerberosArmoring.ps1">Download Script: Configure-EndKerberosArmoring.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Configure-EndKerberosArmoring.ps1
# Description: Configures client-side Kerberos Armoring (FAST) and certificate device authentication on Tier 2 client endpoints.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring on Tier 2 Endpoints..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}

# 1. Enable Kerberos client support for claims and armoring
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord

# 2. Support device authentication using certificate (Automatic)
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord

# 3. Ensure RequireFast is set to 0 (Opportunistic negotiation for general client workstations)
Set-ItemProperty -Path $ClientRegPath -Name "RequireFast" -Value 0 -Type DWord

Write-Host "Client endpoint Kerberos Armoring configured successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the setting has been applied:</xhtml:em>
          <xhtml:a href="audit_scripts/Get-EndKerberosArmoringStatus.ps1">Download Script: Get-EndKerberosArmoringStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code># Get-EndKerberosArmoringStatus.ps1
# Description: Audits client-side Kerberos Armoring configuration on Tier 2 endpoints.

Write-Host "--- Auditing Endpoint Kerberos Armoring Configuration ---" -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
$Vulnerable = $false

$ClientValue = Get-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -ErrorAction SilentlyContinue
$DevicePKInit = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -ErrorAction SilentlyContinue
$DeviceBehavior = Get-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -ErrorAction SilentlyContinue
$RequireFast = Get-ItemProperty -Path $ClientRegPath -Name "RequireFast" -ErrorAction SilentlyContinue

# 1. Audit Client-side support for claims and armoring
if ($null -ne $ClientValue -and $ClientValue.EnableCbacAndArmor -eq 1) {
    Write-Host "[+] Client-side Kerberos Armoring is ENABLED (EnableCbacAndArmor = 1)." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Client-side Kerberos Armoring is DISABLED or missing." -ForegroundColor Red
    $Vulnerable = $true
}

# 2. Audit Certificate device authentication
if ($null -ne $DevicePKInit -and $DevicePKInit.DevicePKInitEnabled -eq 1 -and $null -ne $DeviceBehavior -and $DeviceBehavior.DevicePKInitBehavior -eq 0) {
    Write-Host "[+] Certificate device authentication is ENABLED: Automatic." -ForegroundColor Green
} else {
    Write-Host "[!] VULNERABLE: Certificate device authentication is not compliant or not configured." -ForegroundColor Red
    $Vulnerable = $true
}

# 3. Audit RequireFast (for endpoints, 0 or absent is acceptable for opportunistic FAST)
if ($null -eq $RequireFast -or $RequireFast.RequireFast -eq 0) {
    Write-Host "[+] Kerberos Armoring mode is configured for opportunistic negotiation (RequireFast = 0)." -ForegroundColor Green
} else {
    Write-Host "[-] Information: RequireFast is set to $($RequireFast.RequireFast)." -ForegroundColor Yellow
}

if ($Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <fix system="urn:xccdf:fix:script:powershell"># Configure-EndKerberosArmoring.ps1
# Description: Configures client-side Kerberos Armoring (FAST) and certificate device authentication on Tier 2 client endpoints.

Write-Host "Applying hardening requirement: Enable Kerberos Armoring on Tier 2 Endpoints..." -ForegroundColor Cyan

$ClientRegPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"

if (-not (Test-Path $ClientRegPath)) {
    New-Item -Path $ClientRegPath -Force | Out-Null
}

# 1. Enable Kerberos client support for claims and armoring
Set-ItemProperty -Path $ClientRegPath -Name "EnableCbacAndArmor" -Value 1 -Type DWord

# 2. Support device authentication using certificate (Automatic)
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitEnabled" -Value 1 -Type DWord
Set-ItemProperty -Path $ClientRegPath -Name "DevicePKInitBehavior" -Value 0 -Type DWord

# 3. Ensure RequireFast is set to 0 (Opportunistic negotiation for general client workstations)
Set-ItemProperty -Path $ClientRegPath -Name "RequireFast" -Value 0 -Type DWord

Write-Host "Client endpoint Kerberos Armoring configured successfully." -ForegroundColor Green</fix>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8178" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-179" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-179] Administrative Templates: Disable SMBv1 Protocol Components</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-168](../../07-paws/admin-templates/configure-paw-at-smbv1.md); for Domain Controllers, refer to [REQ-DC-016](../../02-domain-controllers/disable-smbv1.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-smbv1.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Server Message Block version 1 (SMBv1) is a legacy file and print sharing protocol designed in the early 1980s that suffers from severe architectural design flaws, obsolete cryptographic mechanisms, and extensive vulnerabilities exploited in widespread cyberattacks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Lanman Workstation</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure SMB v1 client driver</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set <xhtml:strong>Driver state</xhtml:strong> drop-down to: <xhtml:code>Disable driver (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\Lanman Server</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure SMB v1 server</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across endpoints using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtSmbv1.ps1">Download Script: Configure-EndAtSmbv1.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtSmbv1.ps1
# Description: Configures Administrative Templates: Disable SMBv1 Protocol Components.

Write-Host "Configuring Administrative Templates: Disable SMBv1 Protocol Components..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10" -Name "Start" -Value 4 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "SMB1" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable SMBv1 Protocol Components applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtSmbv1Status.ps1">Download Script: Get-EndAtSmbv1Status.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtSmbv1Status.ps1
# Description: Audits Administrative Templates: Disable SMBv1 Protocol Components.

Write-Host "--- Auditing Administrative Templates: Disable SMBv1 Protocol Components ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10"
$ValueName = "Start"
$ExpectedValue = 4
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$ValueName = "SMB1"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8179" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-180" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-180] Administrative Templates: Configure NetBT Node Type and Name Release</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-169](../../07-paws/admin-templates/configure-paw-at-netbt-nodetype.md); for Domain Controllers, refer to [REQ-DC-017](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-netbt-nodetype.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>NetBIOS over TCP/IP (NetBT, defined in RFC 1001/1002) is a legacy name resolution and session transport protocol that relies heavily on unauthenticated IP broadcasts over UDP port 137. In modern enterprise environments, NetBT introduces significant attack vectors that can be weaponized for credential theft and denial of service.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Network\TCPIP Settings\Parameters</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>NetBT NodeType configuration</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Set <xhtml:strong>NetBT NodeType</xhtml:strong> drop-down to: <xhtml:code>P-node (recommended)</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtNetbtNodetype.ps1">Download Script: Configure-EndAtNetbtNodetype.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtNetbtNodetype.ps1
# Description: Configures Administrative Templates: Configure NetBT Node Type and Name Release.

Write-Host "Configuring Administrative Templates: Configure NetBT Node Type and Name Release..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Name "NodeType" -Value 2 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" -Name "NoNameReleaseOnDemand" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure NetBT Node Type and Name Release applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtNetbtNodetypeStatus.ps1">Download Script: Get-EndAtNetbtNodetypeStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtNetbtNodetypeStatus.ps1
# Description: Audits Administrative Templates: Configure NetBT Node Type and Name Release.

Write-Host "--- Auditing Administrative Templates: Configure NetBT Node Type and Name Release ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters"
$ValueName = "NodeType"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters"
$ValueName = "NoNameReleaseOnDemand"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8180" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-181" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-181] Administrative Templates: MSS IP Source Routing and ICMP Redirects</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-170](../../07-paws/admin-templates/configure-paw-at-mss-ip-source-routing.md); for Domain Controllers, refer to [REQ-DC-018](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-mss-ip-source-routing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Internet Protocol suite (IPv4 RFC 791 and IPv6 RFC 2460/8200) contains legacy diagnostic and routing mechanisms that allow packet senders and adjacent network nodes to manipulate routing decisions. In hostile or untrusted network environments, these capabilities introduce critical exposure to packet spoofing, firewall evasion, and adversary-in-the-middle attacks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (DisableIPSourceRouting IPv6) IP source routing protection level</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Highest protection, source routing is completely disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (DisableIPSourceRouting) IP source routing protection level</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Highest protection, source routing is completely disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify replication using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtMssIpSourceRouting.ps1">Download Script: Configure-EndAtMssIpSourceRouting.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtMssIpSourceRouting.ps1
# Description: Configures Administrative Templates: MSS IP Source Routing and ICMP Redirects.

Write-Host "Configuring Administrative Templates: MSS IP Source Routing and ICMP Redirects..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Name "DisableIPSourceRouting" -Value 2 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "DisableIPSourceRouting" -Value 2 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "EnableICMPRedirect" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: MSS IP Source Routing and ICMP Redirects applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtMssIpSourceRoutingStatus.ps1">Download Script: Get-EndAtMssIpSourceRoutingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtMssIpSourceRoutingStatus.ps1
# Description: Audits Administrative Templates: MSS IP Source Routing and ICMP Redirects.

Write-Host "--- Auditing Administrative Templates: MSS IP Source Routing and ICMP Redirects ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
$ValueName = "DisableIPSourceRouting"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ValueName = "DisableIPSourceRouting"
$ExpectedValue = 2
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$ValueName = "EnableICMPRedirect"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8181" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-182" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-182] Administrative Templates: MSS System and Session Security Protections</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-mss-system-protections.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Microsoft Solutions for Security (MSS) baseline settings provide low-level kernel, session manager, and authentication subsystem protections. These settings address fundamental Windows operating system security behaviors, including DLL search-order resolution, automatic logon credential storage, physical console lockout latency, and security event log capacity alerting.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following MSS policies (imported via <xhtml:code>Secedit</xhtml:code> or Microsoft Security Compliance Toolkit):</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (AutoAdminLogon) Enable Automatic Logon</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (SafeDllSearchMode) Enable Safe DLL search mode</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires</xhtml:em>*: Set to <xhtml:code>Enabled: 5 or fewer seconds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning</xhtml:em>*: Set to <xhtml:code>Enabled: 90% or less</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtMssSystemProtections.ps1">Download Script: Configure-EndAtMssSystemProtections.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtMssSystemProtections.ps1
# Description: Configures Administrative Templates: MSS System and Session Security Protections.

Write-Host "Configuring Administrative Templates: MSS System and Session Security Protections..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoAdminLogon" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "ScreenSaverGracePeriod" -Value 5 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "SafeDllSearchMode" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security")) {
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security" -Name "WarningLevel" -Value 90 -Type DWord -Force

Write-Host "[+] Administrative Templates: MSS System and Session Security Protections applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtMssSystemProtectionsStatus.ps1">Download Script: Get-EndAtMssSystemProtectionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtMssSystemProtectionsStatus.ps1
# Description: Audits Administrative Templates: MSS System and Session Security Protections.

Write-Host "--- Auditing Administrative Templates: MSS System and Session Security Protections ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$ValueName = "AutoAdminLogon"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$ValueName = "ScreenSaverGracePeriod"
$ExpectedValue = 5
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$ValueName = "SafeDllSearchMode"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Security"
$ValueName = "WarningLevel"
$ExpectedValue = 90
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v ScreenSaverGracePeriod reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v SafeDllSearchMode reg query "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Security" /v WarningLevel </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text AutoAdminLogon            REG_SZ       0 ScreenSaverGracePeriod    REG_DWORD    0x5 SafeDllSearchMode         REG_DWORD    0x1 WarningLevel              REG_DWORD    0x5a </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8182" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-183" severity="low" weight="10.0" selected="false">
      <title>[REQ-END-183] Administrative Templates: Prevent Device Metadata Retrieval from Network</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-device-metadata.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>When physical or virtual peripherals—such as USB security tokens, smart card readers, external storage media, printers, or network adapters—are connected to a Windows system, the Device Setup Manager (DSM) initiates automated queries to Microsoft Windows Metadata and Internet Services (WMIS). These services deliver OEM-branded device icons, detailed model descriptions, and companion application links displayed in the "Devices and Printers" interface.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Device Installation</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Prevent device metadata retrieval from the Internet</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtDeviceMetadata.ps1">Download Script: Configure-EndAtDeviceMetadata.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtDeviceMetadata.ps1
# Description: Configures Administrative Templates: Prevent Device Metadata Retrieval from Network.

Write-Host "Configuring Administrative Templates: Prevent Device Metadata Retrieval from Network..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Prevent Device Metadata Retrieval from Network applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtDeviceMetadataStatus.ps1">Download Script: Get-EndAtDeviceMetadataStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtDeviceMetadataStatus.ps1
# Description: Audits Administrative Templates: Prevent Device Metadata Retrieval from Network.

Write-Host "--- Auditing Administrative Templates: Prevent Device Metadata Retrieval from Network ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata"
$ValueName = "PreventDeviceMetadataFromNetwork"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v PreventDeviceMetadataFromNetwork </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text PreventDeviceMetadataFromNetwork    REG_DWORD    0x1 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8183" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-184" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-184] Administrative Templates: Enforce Group Policy Background Processing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-gp-processing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Group Policy service (<xhtml:code>gpsvc</xhtml:code>) manages operating system and security configurations through Client-Side Extensions (CSEs). To minimize network overhead and processing latency, the default Windows Group Policy engine implements an optimization check: during periodic background refresh cycles (every 90 minutes with a randomized 30-minute delta), CSEs compare the local GPO version with the Active Directory SYSVOL version. If the GPO version has not incremented, the CSE skips applying settings.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Group Policy</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure registry policy processing</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Uncheck </xhtml:em>
            <xhtml:em>Do not apply during periodic background processing</xhtml:em>*.</xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure security policy processing</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Check </xhtml:em>
            <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>*.</xhtml:li>
          <xhtml:li>
            <xhtml:em> Uncheck </xhtml:em>
            <xhtml:em>Do not apply during periodic background processing</xhtml:em>*.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for both policies.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtGpProcessing.ps1">Download Script: Configure-EndAtGpProcessing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtGpProcessing.ps1
# Description: Configures Administrative Templates: Enforce Group Policy Background Processing.

Write-Host "Configuring Administrative Templates: Enforce Group Policy Background Processing..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Name "NoBackgroundPolicy" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" -Name "NoGPOListChanges" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Name "NoBackgroundPolicy" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" -Name "NoGPOListChanges" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Enforce Group Policy Background Processing applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtGpProcessingStatus.ps1">Download Script: Get-EndAtGpProcessingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtGpProcessingStatus.ps1
# Description: Audits Administrative Templates: Enforce Group Policy Background Processing.

Write-Host "--- Auditing Administrative Templates: Enforce Group Policy Background Processing ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}"
$ValueName = "NoBackgroundPolicy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}"
$ValueName = "NoGPOListChanges"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
$ValueName = "NoBackgroundPolicy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
$ValueName = "NoGPOListChanges"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" /s </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>NoBackgroundPolicy</xhtml:code> and <xhtml:code>NoGPOListChanges</xhtml:code> are present and set to <xhtml:code>0x0</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8184" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-185" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-185] Administrative Templates: Disable Cross-Device Experiences</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-cross-device-experiences.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Connected Devices Platform (CDP, also known internally as Project Rome) facilitates device-to-device communication, application activity roaming, session continuation ("Continue on PC"), and cross-device clipboard sharing across Windows, iOS, and Android devices. While convenient for consumer multi-device environments, CDP introduces severe security and data-governance vulnerabilities within corporate enterprise networks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Cross-Device Experiences</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Continue experiences on this device</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtCrossDeviceExperiences.ps1">Download Script: Configure-EndAtCrossDeviceExperiences.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtCrossDeviceExperiences.ps1
# Description: Configures Administrative Templates: Disable Cross-Device Experiences.

Write-Host "Configuring Administrative Templates: Disable Cross-Device Experiences..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableCdp" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Cross-Device Experiences applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtCrossDeviceExperiencesStatus.ps1">Download Script: Get-EndAtCrossDeviceExperiencesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtCrossDeviceExperiencesStatus.ps1
# Description: Audits Administrative Templates: Disable Cross-Device Experiences.

Write-Host "--- Auditing Administrative Templates: Disable Cross-Device Experiences ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "EnableCdp"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v EnableCdp </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text EnableCdp    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8185" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-186" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-186] Administrative Templates: Restrict Internet Communication and Web Downloads</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-175](../../07-paws/admin-templates/configure-paw-at-internet-communication.md); for Domain Controllers, refer to [REQ-DC-027](../../02-domain-controllers/configure-telemetry-privacy.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-internet-communication.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows operating system includes several legacy features designed to download supplemental drivers, wizard components, and third-party web provider templates over unauthenticated internet connections. In enterprise environments, these automated internet interactions expose endpoints to remote code execution and data exfiltration.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off downloading of print drivers over HTTP</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off Internet download for Web publishing and online ordering wizards</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtInternetCommunication.ps1">Download Script: Configure-EndAtInternetCommunication.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtInternetCommunication.ps1
# Description: Configures Administrative Templates: Restrict Internet Communication and Web Downloads.

Write-Host "Configuring Administrative Templates: Restrict Internet Communication and Web Downloads..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers" -Name "DisableWebPnPDownload" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoWebServices" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Restrict Internet Communication and Web Downloads applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtInternetCommunicationStatus.ps1">Download Script: Get-EndAtInternetCommunicationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtInternetCommunicationStatus.ps1
# Description: Audits Administrative Templates: Restrict Internet Communication and Web Downloads.

Write-Host "--- Auditing Administrative Templates: Restrict Internet Communication and Web Downloads ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers"
$ValueName = "DisableWebPnPDownload"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$ValueName = "NoWebServices"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8186" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-187" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-187] Administrative Templates: Block Custom SSPs and APs from Loading into LSASS</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-176](../../07-paws/admin-templates/configure-paw-at-lsa-custom-ssps.md); for complementary LSA Protection, refer to [REQ-END-007](../../08-endpoints/enable-lsa-protection.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (1903 and above) Enterprise/Professional, Windows 11 Enterprise/Pro, Windows Server 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-lsa-custom-ssps.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Local Security Authority Subsystem Service (<xhtml:code>lsass.exe</xhtml:code>) is the central authentication authority in the Windows operating system, responsible for credential validation, token creation, and interactive logons. Security Support Providers (SSPs) and Authentication Packages (APs) execute as dynamic link libraries (DLLs) directly inside the <xhtml:code>lsass.exe</xhtml:code> memory space.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Local Security Authority</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow Custom SSPs and APs to be loaded into LSASS</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtLsaCustomSsps.ps1">Download Script: Configure-EndAtLsaCustomSsps.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtLsaCustomSsps.ps1
# Description: Configures Administrative Templates: Block Custom SSPs and APs from Loading into LSASS.

Write-Host "Configuring Administrative Templates: Block Custom SSPs and APs from Loading into LSASS..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowCustomSSPsAPs" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Block Custom SSPs and APs from Loading into LSASS applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtLsaCustomSspsStatus.ps1">Download Script: Get-EndAtLsaCustomSspsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtLsaCustomSspsStatus.ps1
# Description: Audits Administrative Templates: Block Custom SSPs and APs from Loading into LSASS.

Write-Host "--- Auditing Administrative Templates: Block Custom SSPs and APs from Loading into LSASS ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "AllowCustomSSPsAPs"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8187" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-188" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-188] Administrative Templates: Logon Display and Credential Restrictions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-177](../../07-paws/admin-templates/configure-paw-at-logon-display-options.md); for Domain Controllers, refer to [REQ-DC-024](../../02-domain-controllers/configure-security-options.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-logon-display-options.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows logon desktop and lock screen represent the physical perimeter of the operating system. In unhardened configurations, the logon interface exposes critical internal network information, leaks corporate usernames, presents weak authentication alternatives, and permits unauthorized network reconfigurations without authentication.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Logon</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Block user from showing account details on sign-in</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not display network selection UI</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not enumerate connected users on domain-joined computers</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off app notifications on the lock screen</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off picture password sign-in</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn on convenience PIN sign-in</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent the use of security questions for local accounts</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure the transmission of the user's password in the content of MPR notifications sent by winlogon</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtLogonDisplayOptions.ps1">Download Script: Configure-EndAtLogonDisplayOptions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtLogonDisplayOptions.ps1
# Description: Configures Administrative Templates: Logon Display and Credential Restrictions.

Write-Host "Configuring Administrative Templates: Logon Display and Credential Restrictions..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "BlockUserFromShowingAccountDetailsOnSignin" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DontDisplayNetworkSelectionUI" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DontEnumerateConnectedUsers" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "DisableLockScreenAppNotifications" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "BlockDomainPicturePassword" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowDomainPINLogon" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "NoLocalPasswordResetQuestions" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableMPR" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Logon Display and Credential Restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtLogonDisplayOptionsStatus.ps1">Download Script: Get-EndAtLogonDisplayOptionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtLogonDisplayOptionsStatus.ps1
# Description: Audits Administrative Templates: Logon Display and Credential Restrictions.

Write-Host "--- Auditing Administrative Templates: Logon Display and Credential Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "BlockUserFromShowingAccountDetailsOnSignin"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DontDisplayNetworkSelectionUI"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DontEnumerateConnectedUsers"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "DisableLockScreenAppNotifications"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "BlockDomainPicturePassword"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "AllowDomainPINLogon"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
$ValueName = "NoLocalPasswordResetQuestions"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "EnableMPR"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8188" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-189" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-189] Administrative Templates: Disable Connected Standby Network Connectivity</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-power-connected-standby.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modern Standby (S0 Low Power Idle) replaced legacy ACPI S3 (Suspend-to-RAM) sleep states in modern enterprise laptops and convertibles. When "Connected Standby" is permitted, the operating system maintains active Wi-Fi, cellular, and Ethernet network adapters while the display is powered off and the system is suspended. This architecture enables background applications to process incoming push notifications, sync mailboxes, and maintain persistent cloud sockets while unattended.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Power Management\Sleep Settings</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow network connectivity during connected-standby (on battery)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow network connectivity during connected-standby (plugged in)</xhtml:strong>:</xhtml:li>
          <xhtml:li>
            <xhtml:em> Set to </xhtml:em>
            <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for both policies.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtPowerConnectedStandby.ps1">Download Script: Configure-EndAtPowerConnectedStandby.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtPowerConnectedStandby.ps1
# Description: Configures Administrative Templates: Disable Connected Standby Network Connectivity.

Write-Host "Configuring Administrative Templates: Disable Connected Standby Network Connectivity..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Name "DCSettingIndex" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" -Name "ACSettingIndex" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Connected Standby Network Connectivity applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtPowerConnectedStandbyStatus.ps1">Download Script: Get-EndAtPowerConnectedStandbyStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtPowerConnectedStandbyStatus.ps1
# Description: Audits Administrative Templates: Disable Connected Standby Network Connectivity.

Write-Host "--- Auditing Administrative Templates: Disable Connected Standby Network Connectivity ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9"
$ValueName = "DCSettingIndex"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9"
$ValueName = "ACSettingIndex"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" /s </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text DCSettingIndex    REG_DWORD    0x0 ACSettingIndex    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8189" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-190" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-190] Administrative Templates: Disable Remote Assistance</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-remote-assistance.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Remote Assistance (<xhtml:code>msra.exe</xhtml:code>) allows support personnel to view or remotely control an active user's desktop session across a network. Remote Assistance supports two primary connection modes: solicited (where an end user creates an encrypted invitation ticket) and unsolicited (where an external operator or administrator initiates an uninvited connection to the target workstation via "Offer Remote Assistance").</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\System\Remote Assistance</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Configure Offer Remote Assistance</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtRemoteAssistance.ps1">Download Script: Configure-EndAtRemoteAssistance.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtRemoteAssistance.ps1
# Description: Configures Administrative Templates: Disable Remote Assistance.

Write-Host "Configuring Administrative Templates: Disable Remote Assistance..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "fAllowUnsolicited" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Remote Assistance applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtRemoteAssistanceStatus.ps1">Download Script: Get-EndAtRemoteAssistanceStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtRemoteAssistanceStatus.ps1
# Description: Audits Administrative Templates: Disable Remote Assistance.

Write-Host "--- Auditing Administrative Templates: Disable Remote Assistance ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
$ValueName = "fAllowUnsolicited"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fAllowUnsolicited </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text fAllowUnsolicited    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8190" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-191" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-191] Administrative Templates: Enable RPC Endpoint Mapper Client Authentication</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-180](../../07-paws/admin-templates/configure-paw-at-rpc-endpoint-mapper-auth.md); for Domain Controllers, refer to [REQ-DC-018](../../02-domain-controllers/harden-network-parameters.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-rpc-endpoint-mapper-auth.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Remote Procedure Call (RPC) subsystem is fundamental to Windows inter-process communication and remote management. The RPC Endpoint Mapper service (<xhtml:code>epmapper</xhtml:code>, listening on TCP port 135) maintains a dynamic database of RPC servers and maps interface UUIDs to dynamic high-range TCP listening ports (ports 49152–65535).</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Remote Procedure Call</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable RPC Endpoint Mapper Client Authentication</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtRpcEndpointMapperAuth.ps1">Download Script: Configure-EndAtRpcEndpointMapperAuth.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtRpcEndpointMapperAuth.ps1
# Description: Configures Administrative Templates: Enable RPC Endpoint Mapper Client Authentication.

Write-Host "Configuring Administrative Templates: Enable RPC Endpoint Mapper Client Authentication..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" -Name "EnableAuthEpResolution" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Enable RPC Endpoint Mapper Client Authentication applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtRpcEndpointMapperAuthStatus.ps1">Download Script: Get-EndAtRpcEndpointMapperAuthStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtRpcEndpointMapperAuthStatus.ps1
# Description: Audits Administrative Templates: Enable RPC Endpoint Mapper Client Authentication.

Write-Host "--- Auditing Administrative Templates: Enable RPC Endpoint Mapper Client Authentication ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Rpc"
$ValueName = "EnableAuthEpResolution"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8191" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-192" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-192] Administrative Templates: Configure Windows Time Service NTP Client and Server</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-181](../../07-paws/admin-templates/configure-paw-at-w32time-ntp-client.md); for Domain Controllers, refer to [REQ-DC-020](../../02-domain-controllers/configure-pdc-time-sync.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-w32time-ntp-client.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Time Service (<xhtml:code>W32Time</xhtml:code>) is a core architectural component of Windows security, providing synchronization across domain members, member servers, and directory nodes. Precise timekeeping is mandatory for protocol operation, cryptographic authentication, and forensic integrity.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service\Time Providers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable Windows NTP Client</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\System\Windows Time Service\Time Providers</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable Windows NTP Server</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtW32timeNtpClient.ps1">Download Script: Configure-EndAtW32timeNtpClient.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtW32timeNtpClient.ps1
# Description: Configures Administrative Templates: Configure Windows Time Service NTP Client and Server.

Write-Host "Configuring Administrative Templates: Configure Windows Time Service NTP Client and Server..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" -Name "Enabled" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" -Name "Enabled" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure Windows Time Service NTP Client and Server applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtW32timeNtpClientStatus.ps1">Download Script: Get-EndAtW32timeNtpClientStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtW32timeNtpClientStatus.ps1
# Description: Audits Administrative Templates: Configure Windows Time Service NTP Client and Server.

Write-Host "--- Auditing Administrative Templates: Configure Windows Time Service NTP Client and Server ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient"
$ValueName = "Enabled"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer"
$ValueName = "Enabled"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8192" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-193" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-193] Administrative Templates: App Package Deployment Restrictions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-182](../../07-paws/admin-templates/configure-paw-at-appx-deployment-restrictions.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-appx-deployment-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modern Windows application packaging architectures (AppX and MSIX) allow software components to be registered and executed within user profile spaces. In unhardened environments, default deployment behaviors allow standard unprivileged users to install modern packaged applications without administrative oversight or UAC elevation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Package Deployment</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Not allow per-user unsigned packages to install by default (requires explicitly allow per install)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Package Deployment</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent non-admin users from installing packaged Windows apps</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtAppxDeploymentRestrictions.ps1">Download Script: Configure-EndAtAppxDeploymentRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtAppxDeploymentRestrictions.ps1
# Description: Configures Administrative Templates: App Package Deployment Restrictions.

Write-Host "Configuring Administrative Templates: App Package Deployment Restrictions..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Name "DisablePerUserUnsignedPackagesByDefault" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx" -Name "BlockNonAdminUserInstall" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: App Package Deployment Restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtAppxDeploymentRestrictionsStatus.ps1">Download Script: Get-EndAtAppxDeploymentRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtAppxDeploymentRestrictionsStatus.ps1
# Description: Audits Administrative Templates: App Package Deployment Restrictions.

Write-Host "--- Auditing Administrative Templates: App Package Deployment Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx"
$ValueName = "DisablePerUserUnsignedPackagesByDefault"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx"
$ValueName = "BlockNonAdminUserInstall"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8193" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-194" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-194] Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-183](../../07-paws/admin-templates/configure-paw-at-biometrics-anti-spoofing.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-biometrics-anti-spoofing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Hello facial recognition provides convenient, passwordless authentication using biometric verification. However, basic facial recognition systems that analyze only two-dimensional visible spectrum images are vulnerable to presentation attacks and physical spoofing.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Biometrics\Facial Features</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure enhanced anti-spoofing</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtBiometricsAntiSpoofing.ps1">Download Script: Configure-EndAtBiometricsAntiSpoofing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtBiometricsAntiSpoofing.ps1
# Description: Configures Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing.

Write-Host "Configuring Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" -Name "EnhancedAntiSpoofing" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtBiometricsAntiSpoofingStatus.ps1">Download Script: Get-EndAtBiometricsAntiSpoofingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtBiometricsAntiSpoofingStatus.ps1
# Description: Audits Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing.

Write-Host "--- Auditing Administrative Templates: Configure Biometrics Enhanced Anti-Spoofing ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures"
$ValueName = "EnhancedAntiSpoofing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8194" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-195" severity="low" weight="10.0" selected="false">
      <title>[REQ-END-195] Administrative Templates: Disable Cloud Consumer Account State Content</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-cloud-consumer-content.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modern editions of Windows integrate consumer-focused features into the desktop shell and operating system menus. These features display dynamic promotional cards, suggestions for Microsoft consumer cloud services (such as personal OneDrive, Microsoft 365 consumer subscriptions, and personal Microsoft Accounts), and personalized application recommendations directly within core UI components like the Start Menu, Settings app, File Explorer, and Lock Screen.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Cloud Content</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Turn off cloud consumer account state content</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and initiate policy replication across all Domain Controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtCloudConsumerContent.ps1">Download Script: Configure-EndAtCloudConsumerContent.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtCloudConsumerContent.ps1
# Description: Configures Administrative Templates: Disable Cloud Consumer Account State Content.

Write-Host "Configuring Administrative Templates: Disable Cloud Consumer Account State Content..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableConsumerAccountStateContent" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Cloud Consumer Account State Content applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtCloudConsumerContentStatus.ps1">Download Script: Get-EndAtCloudConsumerContentStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtCloudConsumerContentStatus.ps1
# Description: Audits Administrative Templates: Disable Cloud Consumer Account State Content.

Write-Host "--- Auditing Administrative Templates: Disable Cloud Consumer Account State Content ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent"
$ValueName = "DisableConsumerAccountStateContent"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableConsumerAccountStateContent </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text DisableConsumerAccountStateContent    REG_DWORD    0x1 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8195" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-196" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-196] Administrative Templates: Require PIN for Connect Wireless Pairing</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-185](../../07-paws/admin-templates/configure-paw-at-connect-pin-pairing.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-connect-pin-pairing.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Connect application enables endpoints to function as wireless display receivers using the Miracast standard over Wi-Fi Direct (IEEE 802.11 P2P). While useful for collaborative screen projection in meeting rooms, unauthenticated wireless display pairing introduces severe physical perimeter attack vectors.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Connect</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Require pin for pairing</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>First Time</xhtml:code> (or <xhtml:code>Always</xhtml:code> for high-security areas)</xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtConnectPinPairing.ps1">Download Script: Configure-EndAtConnectPinPairing.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtConnectPinPairing.ps1
# Description: Configures Administrative Templates: Require PIN for Connect Wireless Pairing.

Write-Host "Configuring Administrative Templates: Require PIN for Connect Wireless Pairing..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect" -Name "RequirePinForPairing" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Require PIN for Connect Wireless Pairing applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtConnectPinPairingStatus.ps1">Download Script: Get-EndAtConnectPinPairingStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtConnectPinPairingStatus.ps1
# Description: Audits Administrative Templates: Require PIN for Connect Wireless Pairing.

Write-Host "--- Auditing Administrative Templates: Require PIN for Connect Wireless Pairing ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Connect"
$ValueName = "RequirePinForPairing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8196" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-197" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-197] Administrative Templates: Credential User Interface Security Protections</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-186](../../07-paws/admin-templates/configure-paw-at-credui-protections.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-credui-protections.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Credential User Interface (CredUI) handles password collection dialogs and User Account Control (UAC) elevation prompts. In default configurations, CredUI exposes cleartext credentials on screen and leaks local administrative usernames to unprivileged operators.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Credential User Interface</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not display the password reveal button</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Credential User Interface</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enumerate administrator accounts on elevation</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtCreduiProtections.ps1">Download Script: Configure-EndAtCreduiProtections.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtCreduiProtections.ps1
# Description: Configures Administrative Templates: Credential User Interface Security Protections.

Write-Host "Configuring Administrative Templates: Credential User Interface Security Protections..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI" -Name "DisablePasswordReveal" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" -Name "EnumerateAdministrators" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Credential User Interface Security Protections applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtCreduiProtectionsStatus.ps1">Download Script: Get-EndAtCreduiProtectionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtCreduiProtectionsStatus.ps1
# Description: Audits Administrative Templates: Credential User Interface Security Protections.

Write-Host "--- Auditing Administrative Templates: Credential User Interface Security Protections ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredUI"
$ValueName = "DisablePasswordReveal"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI"
$ValueName = "EnumerateAdministrators"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8197" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-198" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-198] Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-data-collection-preview-builds.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Diagnostic Data Collection infrastructure collects system health, performance metrics, crash dumps, and telemetry data for transmission to Microsoft cloud services. Concurrently, the Windows Insider Program allows systems to receive pre-release operating system builds. In managed enterprise environments, unrestricted diagnostic data collection and preview builds introduce serious data leakage and operational stability risks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Data Collection and Preview Builds</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Disable OneSettings Downloads</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Do not show feedback notifications</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Enable OneSettings Auditing</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Limit Diagnostic Log Collection</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Limit Dump Collection</xhtml:em>*: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Toggle user control over Insider builds</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtDataCollectionPreviewBuilds.ps1">Download Script: Configure-EndAtDataCollectionPreviewBuilds.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtDataCollectionPreviewBuilds.ps1
# Description: Configures Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions.

Write-Host "Configuring Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DisableOneSettingsDownloads" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DoNotShowFeedbackNotifications" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "EnableOneSettingsAuditing" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "LimitDiagnosticLogCollection" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "LimitDumpCollection" -Value 1 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" -Name "AllowBuildPreview" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtDataCollectionPreviewBuildsStatus.ps1">Download Script: Get-EndAtDataCollectionPreviewBuildsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtDataCollectionPreviewBuildsStatus.ps1
# Description: Audits Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions.

Write-Host "--- Auditing Administrative Templates: Diagnostic Data Collection and Preview Builds Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "DisableOneSettingsDownloads"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "DoNotShowFeedbackNotifications"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "EnableOneSettingsAuditing"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "LimitDiagnosticLogCollection"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$ValueName = "LimitDumpCollection"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds"
$ValueName = "AllowBuildPreview"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v AllowBuildPreview </xhtml:code>
          <xhtml:code /> Verify the expected DWORD values: <xhtml:code />
          <xhtml:code>text DisableOneSettingsDownloads     REG_DWORD    0x1 DoNotShowFeedbackNotifications  REG_DWORD    0x1 EnableOneSettingsAuditing       REG_DWORD    0x1 LimitDiagnosticLogCollection    REG_DWORD    0x1 LimitDumpCollection             REG_DWORD    0x1 AllowBuildPreview               REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8198" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-199" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-199] Administrative Templates: App Installer Protocol and Execution Controls</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-188](../../07-paws/admin-templates/configure-paw-at-app-installer-controls.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (1709 and above) Enterprise/Professional, Windows 11 Enterprise/Pro, Windows Server 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-app-installer-controls.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows App Installer (<xhtml:code>AppInstaller.exe</xhtml:code>) provides deployment capabilities for MSIX, AppX, and <xhtml:code>.appinstaller</xhtml:code> manifest packages. In default client configurations, App Installer registers the <xhtml:code>ms-appinstaller://</xhtml:code> uniform resource identifier (URI) scheme, allowing web pages to directly trigger package installation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\App Installer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer ms-appinstaller protocol</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Experimental Features</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Hash Override</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Local Archive Malware Scan Override</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Enable App Installer Microsoft Store Source Certificate Validation Bypass</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtAppInstallerControls.ps1">Download Script: Configure-EndAtAppInstallerControls.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtAppInstallerControls.ps1
# Description: Configures Administrative Templates: App Installer Protocol and Execution Controls.

Write-Host "Configuring Administrative Templates: App Installer Protocol and Execution Controls..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableExperimentalFeatures" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableHashOverride" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableLocalArchiveMalwareScanOverride" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableBypassCertificatePinningForMicrosoftStore" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" -Name "EnableMSAppInstallerProtocol" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: App Installer Protocol and Execution Controls applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtAppInstallerControlsStatus.ps1">Download Script: Get-EndAtAppInstallerControlsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtAppInstallerControlsStatus.ps1
# Description: Audits Administrative Templates: App Installer Protocol and Execution Controls.

Write-Host "--- Auditing Administrative Templates: App Installer Protocol and Execution Controls ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableExperimentalFeatures"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableHashOverride"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableLocalArchiveMalwareScanOverride"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableBypassCertificatePinningForMicrosoftStore"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller"
$ValueName = "EnableMSAppInstallerProtocol"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8199" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-200" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-200] Administrative Templates: Event Log Maximum File Sizes and Retention Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-event-log-sizes.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Default Windows event log capacities (typically 20 MB) rollover within hours during normal workstation activity, and can be completely overwritten within minutes during active security incidents, brute-force attempts, or high-volume administrative operations.</xhtml:p>
        <xhtml:p>In hardened environments enforcing comprehensive audit policies (such as Process Creation with command-line arguments [Event ID 4688], PowerShell Script Block Logging [Event ID 4104], and detailed logon/logoff auditing), workstations typically generate between 100 MB and 300+ MB of security telemetry daily. A legacy 192 MB Security log preserves only 12 to 48 hours of telemetry, creating severe risks for endpoints operating off-network (remote users, field devices) where real-time Windows Event Forwarding (WEF) or SIEM shipping may be delayed.</xhtml:p>
        <xhtml:p>Expanding the <xhtml:strong>Security</xhtml:strong> log to <xhtml:strong>1 GB</xhtml:strong> (<xhtml:code>1,048,576 KB</xhtml:code>), <xhtml:strong>System</xhtml:strong> and <xhtml:strong>Application</xhtml:strong> logs to <xhtml:strong>128 MB</xhtml:strong> (<xhtml:code>131,072 KB</xhtml:code>), and <xhtml:strong>Setup</xhtml:strong> log to <xhtml:strong>32 MB</xhtml:strong> (<xhtml:code>32,768 KB</xhtml:code>) provides a resilient 7-to-14-day on-box forensic retention buffer.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Application</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>131072</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Security</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>1048576</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Setup</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>32768</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\System</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Specify the maximum log file size (KB)</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code> (<xhtml:code>131072</xhtml:code> KB)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Control Event Log behavior when the log file reaches its maximum size</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtEventLogSizes.ps1">Download Script: Configure-EndAtEventLogSizes.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtEventLogSizes.ps1
# Description: Configures Administrative Templates: Event Log Maximum File Sizes and Retention Policies.

Write-Host "Configuring Administrative Templates: Event Log Maximum File Sizes and Retention Policies..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" -Name "MaxSize" -Value 131072 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" -Name "MaxSize" -Value 1048576 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" -Name "MaxSize" -Value 32768 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "Retention" -Value "0" -Type String -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" -Name "MaxSize" -Value 131072 -Type DWord -Force

Write-Host "[+] Administrative Templates: Event Log Maximum File Sizes and Retention Policies applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtEventLogSizesStatus.ps1">Download Script: Get-EndAtEventLogSizesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtEventLogSizesStatus.ps1
# Description: Audits Administrative Templates: Event Log Maximum File Sizes and Retention Policies.

Write-Host "--- Auditing Administrative Templates: Event Log Maximum File Sizes and Retention Policies ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application"
$ValueName = "MaxSize"
$ExpectedValue = 131072
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security"
$ValueName = "MaxSize"
$ExpectedValue = 1048576
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup"
$ValueName = "MaxSize"
$ExpectedValue = 32768
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System"
$ValueName = "Retention"
$ExpectedValue = "0"
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\System"
$ValueName = "MaxSize"
$ExpectedValue = 131072
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied log configurations via command line using <xhtml:code>wevtutil</xhtml:code>: <xhtml:code />
          <xhtml:code>cmd wevtutil gl Application wevtutil gl Security wevtutil gl Setup wevtutil gl System </xhtml:code>
          <xhtml:code /> Verify that <xhtml:code>maxSize</xhtml:code> reflects the configured byte values (<xhtml:code>1073741824</xhtml:code> bytes for Security, <xhtml:code>134217728</xhtml:code> bytes for System/Application, <xhtml:code>33554432</xhtml:code> bytes for Setup) and <xhtml:code>retention</xhtml:code> is set to <xhtml:code>false</xhtml:code>.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8200" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-201" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-201] Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-190](../../07-paws/admin-templates/configure-paw-at-file-explorer-motw.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-file-explorer-motw.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Attachment Manager and File Explorer utilize the Mark of the Web (MotW) as a core security boundary. MotW is implemented as an NTFS Alternate Data Stream (ADS) named <xhtml:code>Zone.Identifier</xhtml:code> appended to files downloaded from the internet or untrusted network zones. Maintaining strict MotW integrity and enforcing shell protocol protected mode are essential defenses against initial-access malware campaigns.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\File Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Do not apply the Mark of the Web tag to files copied from insecure sources</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures MotW is applied)</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\File Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off shell protocol protected mode</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures Protected Mode is enforced)</xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtFileExplorerMotw.ps1">Download Script: Configure-EndAtFileExplorerMotw.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtFileExplorerMotw.ps1
# Description: Configures Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security.

Write-Host "Configuring Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "DisableMotWOnInsecurePathCopy" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "PreXPSP2ShellProtocolBehavior" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtFileExplorerMotwStatus.ps1">Download Script: Get-EndAtFileExplorerMotwStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtFileExplorerMotwStatus.ps1
# Description: Audits Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security.

Write-Host "--- Auditing Administrative Templates: File Explorer Mark of the Web and Shell Protocol Security ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer"
$ValueName = "DisableMotWOnInsecurePathCopy"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$ValueName = "PreXPSP2ShellProtocolBehavior"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8201" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-202" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-202] Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-191](../../07-paws/admin-templates/configure-paw-at-internet-explorer-retirement.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-internet-explorer-retirement.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Internet Explorer 11 reached official end-of-life and retirement on modern Windows platforms. The standalone browser executable (<xhtml:code>iexplore.exe</xhtml:code>) lacks contemporary exploit mitigations, process sandboxing, and memory safety defenses, making it a persistent vector for zero-day exploitation and drive-by malware execution.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Disable Internet Explorer 11 as a standalone browser</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Select drop-down value: <xhtml:code>Always</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer\Feeds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Prevent downloading of enclosures</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Internet Explorer\Feeds</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn on Basic feed authentication over HTTP</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtInternetExplorerRetirement.ps1">Download Script: Configure-EndAtInternetExplorerRetirement.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtInternetExplorerRetirement.ps1
# Description: Configures Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls.

Write-Host "Configuring Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" -Name "NotifyDisableIEOptions" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Name "DisableEnclosureDownload" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" -Name "AllowBasicAuthInClear" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtInternetExplorerRetirementStatus.ps1">Download Script: Get-EndAtInternetExplorerRetirementStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtInternetExplorerRetirementStatus.ps1
# Description: Audits Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls.

Write-Host "--- Auditing Administrative Templates: Internet Explorer 11 and Web Feeds Retirement Controls ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main"
$ValueName = "NotifyDisableIEOptions"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds"
$ValueName = "DisableEnclosureDownload"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds"
$ValueName = "AllowBasicAuthInClear"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8202" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-204" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-204] Administrative Templates: Windows Search and Cortana Privacy Restrictions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-search-cortana-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>The Windows Search and Cortana infrastructure provides desktop indexing, voice recognition, and location-aware query capabilities. In enterprise environments, unconstrained search and voice assistant features introduce severe data leakage, physical authentication bypass, and cryptographic exposure risks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Search</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Cortana</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow Cortana above lock screen</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow indexing of encrypted files</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:em> </xhtml:em>
            <xhtml:em>Allow search and Cortana to use location</xhtml:em>*: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong> for each policy.</xhtml:li>
          <xhtml:li>Link the GPO to the target Organizational Unit (OU) and verify replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtSearchCortanaRestrictions.ps1">Download Script: Configure-EndAtSearchCortanaRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtSearchCortanaRestrictions.ps1
# Description: Configures Administrative Templates: Windows Search and Cortana Privacy Restrictions.

Write-Host "Configuring Administrative Templates: Windows Search and Cortana Privacy Restrictions..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowCortana" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowCortanaAboveLock" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowIndexingEncryptedStoresOrItems" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowSearchToUseLocation" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Search and Cortana Privacy Restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtSearchCortanaRestrictionsStatus.ps1">Download Script: Get-EndAtSearchCortanaRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtSearchCortanaRestrictionsStatus.ps1
# Description: Audits Administrative Templates: Windows Search and Cortana Privacy Restrictions.

Write-Host "--- Auditing Administrative Templates: Windows Search and Cortana Privacy Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowCortana"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowCortanaAboveLock"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowIndexingEncryptedStoresOrItems"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
$ValueName = "AllowSearchToUseLocation"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /s </xhtml:code>
          <xhtml:code /> Ensure all four values are present and set to <xhtml:code>0x0</xhtml:code>: <xhtml:code />
          <xhtml:code>text AllowCortana                          REG_DWORD    0x0 AllowCortanaAboveLock                 REG_DWORD    0x0 AllowIndexingEncryptedStoresOrItems   REG_DWORD    0x0 AllowSearchToUseLocation              REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8204" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-205" severity="medium" weight="10.0" selected="false">
      <title>[REQ-END-205] Administrative Templates: Windows Store Updates and OS Upgrade Restrictions</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-194](../../07-paws/admin-templates/configure-paw-at-windows-store-restrictions.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-windows-store-restrictions.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Modern Windows installations incorporate numerous built-in packaged applications, runtime frameworks, and system extensions (such as Windows Terminal, App Installer, HEVC/VP9 codecs, and Edge WebView2 components) that are serviced through the Microsoft Store infrastructure. Managing store update behaviors is essential to ensure critical vulnerability patching while preventing unmanaged operating system upgrades.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Store</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off Automatic Download and Install of updates</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code> (Ensures updates are downloaded automatically)</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Store</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Turn off the offer to update to the latest version of Windows</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtWindowsStoreRestrictions.ps1">Download Script: Configure-EndAtWindowsStoreRestrictions.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtWindowsStoreRestrictions.ps1
# Description: Configures Administrative Templates: Windows Store Updates and OS Upgrade Restrictions.

Write-Host "Configuring Administrative Templates: Windows Store Updates and OS Upgrade Restrictions..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Name "AutoDownload" -Value 4 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Name "DisableOSUpgrade" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Store Updates and OS Upgrade Restrictions applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtWindowsStoreRestrictionsStatus.ps1">Download Script: Get-EndAtWindowsStoreRestrictionsStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtWindowsStoreRestrictionsStatus.ps1
# Description: Audits Administrative Templates: Windows Store Updates and OS Upgrade Restrictions.

Write-Host "--- Auditing Administrative Templates: Windows Store Updates and OS Upgrade Restrictions ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$ValueName = "AutoDownload"
$ExpectedValue = 4
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$ValueName = "DisableOSUpgrade"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8205" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-206" severity="low" weight="10.0" selected="false">
      <title>[REQ-END-206] Administrative Templates: Disable Windows Widgets and News Feed</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-windows-widgets-dsh.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Widgets (in Windows 11) and the earlier News and Interests feature (in Windows 10) integrate dynamic cloud-delivered content directly into the Windows desktop taskbar. The feature relies on the Desktop Shell Host (<xhtml:code>widgets.exe</xhtml:code>) and the Microsoft Edge WebView2 runtime to continuously retrieve and display news feeds, weather reports, sports scores, stock tickers, and third-party sponsored advertisements.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Navigate to:</xhtml:li>
          <xhtml:li>
            <xhtml:code />`text</xhtml:li>
          <xhtml:li>Computer Configuration\Policies\Administrative Templates\Windows Components\Widgets</xhtml:li>
          <xhtml:li>
            <xhtml:code />
            <xhtml:code />
          </xhtml:li>
          <xhtml:li>Double-click <xhtml:strong>Allow widgets</xhtml:strong>.</xhtml:li>
          <xhtml:li>Select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong>, then click <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtWindowsWidgetsDsh.ps1">Download Script: Configure-EndAtWindowsWidgetsDsh.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtWindowsWidgetsDsh.ps1
# Description: Configures Administrative Templates: Disable Windows Widgets and News Feed.

Write-Host "Configuring Administrative Templates: Disable Windows Widgets and News Feed..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh" -Name "AllowNewsAndInterests" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Windows Widgets and News Feed applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtWindowsWidgetsDshStatus.ps1">Download Script: Get-EndAtWindowsWidgetsDshStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtWindowsWidgetsDshStatus.ps1
# Description: Audits Administrative Templates: Disable Windows Widgets and News Feed.

Write-Host "--- Auditing Administrative Templates: Disable Windows Widgets and News Feed ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Dsh"
$ValueName = "AllowNewsAndInterests"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy setting via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests </xhtml:code>
          <xhtml:code /> Expected output: <xhtml:code />
          <xhtml:code>text AllowNewsAndInterests    REG_DWORD    0x0 </xhtml:code>
          <xhtml:code />
        </xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8206" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-207" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-207] Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO)</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-196](../../07-paws/admin-templates/configure-paw-at-automatic-restart-signon.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-automatic-restart-signon.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Automatic Restart Sign-On (ARSO) is a Windows convenience feature designed to streamline post-update maintenance. When an automated Windows Update requires a reboot, ARSO captures the interactive user's credentials, encrypts them via the Local Security Authority (LSA) and Data Protection API (DPAPI), and stages them across the reboot sequence. Upon restart, Winlogon automatically decrypts the credentials, logs the user on in the background, instantiates the user profile, and locks the console.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Logon Options</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Sign-in and lock last interactive user automatically after a restart</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtAutomaticRestartSignon.ps1">Download Script: Configure-EndAtAutomaticRestartSignon.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtAutomaticRestartSignon.ps1
# Description: Configures Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO).

Write-Host "Configuring Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO)..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")) {
    New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableAutomaticRestartSignOn" -Value 1 -Type DWord -Force

Write-Host "[+] Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtAutomaticRestartSignonStatus.ps1">Download Script: Get-EndAtAutomaticRestartSignonStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtAutomaticRestartSignonStatus.ps1
# Description: Audits Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO).

Write-Host "--- Auditing Administrative Templates: Disable Windows Automatic Restart Sign-On (ARSO) ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ValueName = "DisableAutomaticRestartSignOn"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8207" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-208" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-208] Administrative Templates: Windows Sandbox Clipboard and Network Isolation</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-197](../../07-paws/admin-templates/configure-paw-at-windows-sandbox-isolation.md)).</xhtml:em>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (1903 and above) Enterprise/Professional, Windows 11 Enterprise/Pro.</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-windows-sandbox-isolation.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Sandbox provides a disposable, containerized desktop environment based on Hyper-V virtualization technology. While designed for the isolated execution of untrusted applications and triage of suspicious documents, default sandbox configurations permit bidirectional clipboard synchronization and shared network access, introducing significant breach risks.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Sandbox</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow clipboard sharing with Windows Sandbox</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Sandbox</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Allow networking in Windows Sandbox</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtWindowsSandboxIsolation.ps1">Download Script: Configure-EndAtWindowsSandboxIsolation.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtWindowsSandboxIsolation.ps1
# Description: Configures Administrative Templates: Windows Sandbox Clipboard and Network Isolation.

Write-Host "Configuring Administrative Templates: Windows Sandbox Clipboard and Network Isolation..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Name "AllowClipboardRedirection" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox" -Name "AllowNetworking" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Sandbox Clipboard and Network Isolation applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtWindowsSandboxIsolationStatus.ps1">Download Script: Get-EndAtWindowsSandboxIsolationStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtWindowsSandboxIsolationStatus.ps1
# Description: Audits Administrative Templates: Windows Sandbox Clipboard and Network Isolation.

Write-Host "--- Auditing Administrative Templates: Windows Sandbox Clipboard and Network Isolation ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox"
$ValueName = "AllowClipboardRedirection"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Sandbox"
$ValueName = "AllowNetworking"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8208" />
      </check>
    </Rule>
    <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-209" severity="high" weight="10.0" selected="false">
      <title>[REQ-END-209] Administrative Templates: Windows Update Deferral and Automatic Installation Policies</title>
      <description>
        <xhtml:p>
          <xhtml:strong>Target Scope:</xhtml:strong>
        </xhtml:p>
        <xhtml:ul>
          <xhtml:li>
            <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
        </xhtml:ul>
        <xhtml:p>
          <xhtml:strong>File Path: </xhtml:strong>
          <xhtml:code>08-endpoints/admin-templates/configure-end-at-windows-update-policies.md</xhtml:code>
        </xhtml:p>
      </description>
      <rationale>
        <xhtml:p>Windows Update is the primary defense mechanism against known Common Vulnerabilities and Exposures (CVEs), remote code execution exploits, and privilege escalation vulnerabilities. In unhardened environments, default update policies allow users to pause updates, postpone reboots, or enroll in experimental preview builds, directly exposing the enterprise network to preventable exploitation.</xhtml:p>
      </rationale>
      <fixtext>
        <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
        <xhtml:ol>
          <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
          <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
          <xhtml:li>Configure the following policies:</xhtml:li>
        </xhtml:ol>
        <xhtml:ul>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Update</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Remove access to 'Pause updates' feature</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Manage preview builds</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Select when Preview Builds and Feature Updates are received</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, select <xhtml:strong>Semi-Annual Channel</xhtml:strong>, and set deferral to <xhtml:code>180</xhtml:code> days</xhtml:li>
          <xhtml:li>
            <xhtml:strong>Select when Quality Updates are received</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, set deferral to <xhtml:code>0</xhtml:code> days</xhtml:li>
          <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Update\Manage end user experience</xhtml:code>
          </xhtml:li>
          <xhtml:li>
            <xhtml:strong>Configure Automatic Updates</xhtml:strong>: Set to <xhtml:code>Enabled</xhtml:code>, select option <xhtml:strong>4 - Auto download and schedule the install</xhtml:strong>, set scheduled install day to <xhtml:code>0 - Every day</xhtml:code>, and configure a suitable maintenance hour (e.g., <xhtml:code>03:00</xhtml:code>)</xhtml:li>
          <xhtml:li>
            <xhtml:strong>No auto-restart with logged on users for scheduled automatic updates installations</xhtml:strong>: Set to <xhtml:code>Disabled</xhtml:code>
          </xhtml:li>
        </xhtml:ul>
        <xhtml:ol>
          <xhtml:li>Link the GPO to the appropriate Organizational Unit (OU) and verify policy replication across all domain controllers.</xhtml:li>
        </xhtml:ol>
        <xhtml:hr />
        <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
        <xhtml:p>Run the following script locally to configure the administrative template registry values:</xhtml:p>
        <xhtml:p>
          <xhtml:a href="../implementation_scripts/Configure-EndAtWindowsUpdatePolicies.ps1">Download Script: Configure-EndAtWindowsUpdatePolicies.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Configure-EndAtWindowsUpdatePolicies.ps1
# Description: Configures Administrative Templates: Windows Update Deferral and Automatic Installation Policies.

Write-Host "Configuring Administrative Templates: Windows Update Deferral and Automatic Installation Policies..." -ForegroundColor Cyan

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "SetDisablePauseUXAccess" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ManagePreviewBuildsPolicyValue" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferFeatureUpdates" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferFeatureUpdatesPeriodInDays" -Value 180 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferQualityUpdates" -Value 1 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferQualityUpdatesPeriodInDays" -Value 0 -Type DWord -Force

if (-not (Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU")) {
    New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force | Out-Null
}
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "ScheduledInstallDay" -Value 0 -Type DWord -Force

Write-Host "[+] Administrative Templates: Windows Update Deferral and Automatic Installation Policies applied successfully." -ForegroundColor Green</xhtml:code>
        </xhtml:pre>
        <xhtml:p>
          <xhtml:em>To verify the configuration:</xhtml:em>
        </xhtml:p>
        <xhtml:p>
          <xhtml:a href="../audit_scripts/Get-EndAtWindowsUpdatePoliciesStatus.ps1">Download Script: Get-EndAtWindowsUpdatePoliciesStatus.ps1</xhtml:a>
        </xhtml:p>
        <xhtml:pre>
          <xhtml:code>#Get-EndAtWindowsUpdatePoliciesStatus.ps1
# Description: Audits Administrative Templates: Windows Update Deferral and Automatic Installation Policies.

Write-Host "--- Auditing Administrative Templates: Windows Update Deferral and Automatic Installation Policies ---" -ForegroundColor Cyan
$script:Vulnerable = $false

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "SetDisablePauseUXAccess"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "ManagePreviewBuildsPolicyValue"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferFeatureUpdates"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferFeatureUpdatesPeriodInDays"
$ExpectedValue = 180
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferQualityUpdates"
$ExpectedValue = 1
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$ValueName = "DeferQualityUpdatesPeriodInDays"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$ValueName = "NoAutoRebootWithLoggedOnUsers"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

$TargetKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$ValueName = "ScheduledInstallDay"
$ExpectedValue = 0
if (Test-Path -Path $TargetKey) {
    $Prop = Get-ItemProperty -Path $TargetKey -Name $ValueName -ErrorAction SilentlyContinue
    if ($null -ne $Prop) {
        $Actual = $Prop.$ValueName
        if ($Actual -eq $ExpectedValue) {
            Write-Host "  [+] $ValueName = $($Actual) (Secure)" -ForegroundColor Green
        } else {
            Write-Host "  [!] MISMATCH: $ValueName = $($Actual) (Expected: $($ExpectedValue))" -ForegroundColor Red
            $script:Vulnerable = $true
        }
    } else {
        Write-Host "  [!] MISSING VALUE: $ValueName (Expected: $($ExpectedValue))" -ForegroundColor Red
        $script:Vulnerable = $true
    }
} else {
    Write-Host "  [!] MISSING KEY: $TargetKey" -ForegroundColor Red
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
        </xhtml:pre>
        <xhtml:hr />
        <xhtml:h3>Option C: Manual Verification</xhtml:h3>
        <xhtml:p>Verify the applied policy settings via administrative command prompt: <xhtml:code />
          <xhtml:code>cmd reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" /s reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /s </xhtml:code>
          <xhtml:code /> Verify that all configured values match the defined baseline.</xhtml:p>
        <xhtml:hr />
      </fixtext>
      <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
        <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8209" />
      </check>
    </Rule>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_Defender_Antivirus">
      <title>Defender Antivirus</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-057" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-057] Disable Real-Time Monitoring and Behavior Monitoring Override</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/disable-real-time-monitoring-and-behavior-monitoring-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Real-time scanning, behavior monitoring, and script checking are the core dynamic defense mechanisms of Windows Defender. Disabling or bypassing these controls allows malicious scripts, file-based attacks, and unauthorized in-memory activities to execute undetected.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Turn off real-time protection' to 'Disabled'</xhtml:li>
            <xhtml:li>Set 'Turn on behavior monitoring' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Scan all downloaded files and attachments' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on script scanning' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderRtp.ps1">Download Script: Configure-DefenderRtp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderRtp.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderRtpStatus.ps1">Download Script: Get-DefenderRtpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderRtpStatus.ps1
$Pref = Get-MpPreference
if ($Pref.DisableRealtimeMonitoring -eq $false -and $Pref.DisableBehaviorMonitoring -eq $false -and $Pref.DisableIOAVProtection -eq $false -and $Pref.DisableScriptScanning -eq $false) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderRtp.ps1
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8057" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-058" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-058] Configure Potentially Unwanted Applications (PUA) Protection</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-potentially-unwanted-applications-pua-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Potentially Unwanted Applications (PUA) include adware, torrent clients, cryptominers, and system optimizers that increase risk and resource consumption. Forcing PUA blocking stops standard vectors of shadow IT and unauthorized utility tool execution.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure detection for potentially unwanted applications' to 'Enabled'</xhtml:li>
            <xhtml:li>Select 'Block' in the options dropdown list</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderPUA.ps1">Download Script: Configure-DefenderPUA.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderPUAStatus.ps1">Download Script: Get-DefenderPUAStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderPUAStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -ErrorAction SilentlyContinue
if ($Pref.PUAProtection -eq 1 -or ($Reg -and $Reg.PUAProtection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderPUA.ps1
Set-MpPreference -PUAProtection 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8058" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-059" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-059] Prevent Local List Merging and Exclusions Configuration</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/prevent-local-list-merging-and-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>If local administrators or compromised administrative accounts can modify Defender exclusions or merge local lists, they can authorize malicious folders or tools. Restricting list configuration to central GPOs ensures consistent security enforcement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus</xhtml:li>
            <xhtml:li>Set 'Configure local administrator merge behavior for lists' to 'Disabled'</xhtml:li>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Prevent users from configuring exclusions' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Control whether or not exclusions are visible to Local Admins' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderLocalExclusions.ps1">Download Script: Configure-DefenderLocalExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderLocalExclusionsStatus.ps1">Download Script: Get-DefenderLocalExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderLocalExclusionsStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableLocalAdminMerge" -ErrorAction SilentlyContinue
$RegHide = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "HideExclusionsFromLocalAdmins" -ErrorAction SilentlyContinue
$RegConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableLocalAdminConfiguration" -ErrorAction SilentlyContinue
if (($Pref.DisableLocalAdminMerge -eq $true -or ($Reg -and $Reg.DisableLocalAdminMerge -eq 1)) -and
    ($RegHide -and $RegHide.HideExclusionsFromLocalAdmins -eq 1) -and
    ($RegConfig -and $RegConfig.DisableLocalAdminConfiguration -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderLocalExclusions.ps1
Set-MpPreference -DisableLocalAdminMerge $true
Set-MpPreference -DisableExclusionRestriction $false
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableLocalAdminMerge" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "HideExclusionsFromLocalAdmins" -Value 1 -Type DWord -Force
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableLocalAdminConfiguration" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8059" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-060" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-060] Configure Auto Exclusions Configuration</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-auto-exclusions-configuration.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auto Exclusions automatically configure exclusions for known safe system folders or server roles to reduce performance overhead. Enforcing that auto exclusions are not disabled ensures server performance stability and proper system scanning.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Exclusions</xhtml:li>
            <xhtml:li>Set 'Turn off Auto Exclusions' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderAutoExclusions.ps1">Download Script: Configure-DefenderAutoExclusions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderAutoExclusionsStatus.ps1">Download Script: Get-DefenderAutoExclusionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderAutoExclusionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions" -Name "DisableAutoExclusions" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.DisableAutoExclusions -eq 0) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderAutoExclusions.ps1
$ExclPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions"
if (-not (Test-Path $ExclPath)) { New-Item -Path $ExclPath -Force | Out-Null }
Set-ItemProperty -Path $ExclPath -Name "DisableAutoExclusions" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8060" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-061" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-061] Prevent MAPS Local Setting Override</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/prevent-maps-local-setting-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Preventing local overrides of Microsoft Active Protection Service (MAPS) reporting ensures that endpoints consistently report telemetry and signature feedback to cloud resources, preserving centralized protective visibility.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\MAPS</xhtml:li>
            <xhtml:li>Set 'Configure local setting override for reporting to Microsoft MAPS' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderMapsOverride.ps1">Download Script: Configure-DefenderMapsOverride.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderMapsOverride.ps1
$SpynetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet"
if (-not (Test-Path $SpynetPath)) { New-Item -Path $SpynetPath -Force | Out-Null }
Set-ItemProperty -Path $SpynetPath -Name "LocalSettingOverrideSpynetReporting" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderMapsOverrideStatus.ps1">Download Script: Get-DefenderMapsOverrideStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderMapsOverrideStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "LocalSettingOverrideSpynetReporting" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.LocalSettingOverrideSpynetReporting -eq 0) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderMapsOverride.ps1
$SpynetPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet"
if (-not (Test-Path $SpynetPath)) { New-Item -Path $SpynetPath -Force | Out-Null }
Set-ItemProperty -Path $SpynetPath -Name "LocalSettingOverrideSpynetReporting" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8061" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-062" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-062] Enable EDR in Block Mode</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/enable-edr-in-block-mode.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Endpoint Detection and Response (EDR) in Block Mode allows Defender to take remediation actions on malicious artifacts detected by Microsoft Defender for Endpoint even if another non-Microsoft antivirus is primary. This establishes secondary defensive block capabilities.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Features</xhtml:li>
            <xhtml:li>Set 'Enable EDR in block mode' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderEdrBlockMode.ps1">Download Script: Configure-DefenderEdrBlockMode.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderEdrBlockModeStatus.ps1">Download Script: Get-DefenderEdrBlockModeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderEdrBlockModeStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features" -Name "PassiveRemediation" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.PassiveRemediation -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderEdrBlockMode.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
Set-ItemProperty -Path $FeaturesPath -Name "PassiveRemediation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8062" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-063" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-063] Allow Network Protection on Windows Server</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/allow-network-protection-on-windows-server.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Network Protection blocks processes from accessing malicious domains, phishing sites, and host IP ranges. Allowing Network Protection on Windows Server ensures that member servers running server workloads possess the same IP filter protections as client platforms.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Network Protection</xhtml:li>
            <xhtml:li>Set 'This setting controls whether Network Protection is allowed to be configured into block or audit mode on Windows Server' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderNetworkProtectionServer.ps1">Download Script: Configure-DefenderNetworkProtectionServer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderNetworkProtectionServerStatus.ps1">Download Script: Get-DefenderNetworkProtectionServerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderNetworkProtectionServerStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" -Name "AllowNetworkProtectionOnWinServer" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.AllowNetworkProtectionOnWinServer -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderNetworkProtectionServer.ps1
$NetProtPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection"
if (-not (Test-Path $NetProtPath)) { New-Item -Path $NetProtPath -Force | Out-Null }
Set-ItemProperty -Path $NetProtPath -Name "AllowNetworkProtectionOnWinServer" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8063" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-064" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-064] Enable File Hash Computation</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/enable-file-hash-computation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Computing cryptographic file hashes allows Defender to pass hashes of scanned files to cloud and SIEM endpoints. This enables precise IOC matches, file tracking, and correlation with threat intelligence repositories.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\MpEngine</xhtml:li>
            <xhtml:li>Set 'Enable file hash computation feature' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderFileHash.ps1">Download Script: Configure-DefenderFileHash.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderFileHashStatus.ps1">Download Script: Get-DefenderFileHashStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderFileHashStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" -Name "EnableFileHashComputation" -ErrorAction SilentlyContinue
if ($Pref.EnableFileHashComputation -eq $true -or ($Reg -and $Reg.EnableFileHashComputation -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderFileHash.ps1
Set-MpPreference -EnableFileHashComputation $true
$MpEnginePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine"
if (-not (Test-Path $MpEnginePath)) { New-Item -Path $MpEnginePath -Force | Out-Null }
Set-ItemProperty -Path $MpEnginePath -Name "EnableFileHashComputation" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8064" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-065" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-065] Configure Network Inspection System (NIS) settings</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-network-inspection-system-nis-settings.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Network Inspection System (NIS) inspects network traffic patterns for known exploits. Converting warning verdicts to block enforces inline blocking of zero-day exploits, while allowing async inspection prevents performance overhead from slowing local network interfaces.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Network Inspection System</xhtml:li>
            <xhtml:li>Set 'Convert warn verdict to block' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on asynchronous inspection' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderNis.ps1">Download Script: Configure-DefenderNis.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderNisStatus.ps1">Download Script: Get-DefenderNisStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderNisStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "EnableConvertWarnToBlock" -ErrorAction SilentlyContinue
$RegAsync = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" -Name "AllowSwitchToAsyncInspection" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.EnableConvertWarnToBlock -eq 1) -and ($RegAsync -and $RegAsync.AllowSwitchToAsyncInspection -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderNis.ps1
$NisPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\NIS"
if (-not (Test-Path $NisPath)) { New-Item -Path $NisPath -Force | Out-Null }
Set-ItemProperty -Path $NisPath -Name "EnableConvertWarnToBlock" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $NisPath -Name "AllowSwitchToAsyncInspection" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8065" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-066" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-066] Configure OOBE Real-Time Protection and Security Intelligence</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-oobe-real-time-protection-and-security-intelligence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling real-time protection and intelligence updates during the Out-of-Box Experience (OOBE) ensures that the system is fully updated and protected before the initial administrative user signs in or connects to enterprise network nodes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Real-time Protection</xhtml:li>
            <xhtml:li>Set 'Configure real-time protection and Security Intelligence Updates during OOBE' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderOobeRtp.ps1">Download Script: Configure-DefenderOobeRtp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderOobeRtpStatus.ps1">Download Script: Get-DefenderOobeRtpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderOobeRtpStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "OobeEnableRtpAndSigUpdate" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.OobeEnableRtpAndSigUpdate -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderOobeRtp.ps1
$RtpPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection"
if (-not (Test-Path $RtpPath)) { New-Item -Path $RtpPath -Force | Out-Null }
Set-ItemProperty -Path $RtpPath -Name "OobeEnableRtpAndSigUpdate" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8066" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-067" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-067] Enable Dynamic Signature Dropped Event Reporting</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/enable-dynamic-signature-dropped-event-reporting.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enabling this log report generation triggers explicit events when a dynamic scan ruleset signature is dropped. This ensures SIEM integrations can immediately log changes in the local threat signatures dataset.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Reporting</xhtml:li>
            <xhtml:li>Set 'Configure whether to report Dynamic Signature dropped events' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderDynamicReporting.ps1">Download Script: Configure-DefenderDynamicReporting.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderDynamicReportingStatus.ps1">Download Script: Get-DefenderDynamicReportingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderDynamicReportingStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" -Name "EnableDynamicSignatureDroppedEventReporting" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.EnableDynamicSignatureDroppedEventReporting -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderDynamicReporting.ps1
$RepPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting"
if (-not (Test-Path $RepPath)) { New-Item -Path $RepPath -Force | Out-Null }
Set-ItemProperty -Path $RepPath -Name "EnableDynamicSignatureDroppedEventReporting" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8067" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-068" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-068] Configure Quick Scan and Scanning Exclusions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-quick-scan-and-scanning-exclusions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Malware frequently tries to establish persistence in excluded directories or inside packed/compressed executables. Forcing quick scans to include excluded files and ensuring packed file structures are recursively scanned prevents malware evasion.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Scan excluded files and directories during quick scans' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn off scanning of packed executables' to 'Disabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderQuickScan.ps1">Download Script: Configure-DefenderQuickScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderQuickScanStatus.ps1">Download Script: Get-DefenderQuickScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderQuickScanStatus.ps1
$Pref = Get-MpPreference
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "QuickScanIncludeExclusions" -ErrorAction SilentlyContinue
$RegPack = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DisablePackedExeScanning" -ErrorAction SilentlyContinue
if (($Pref.DisablePackedExeScanning -eq $false -or ($RegPack -and $RegPack.DisablePackedExeScanning -eq 0)) -and
    ($Reg -and $Reg.QuickScanIncludeExclusions -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderQuickScan.ps1
Set-MpPreference -DisablePackedExeScanning $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "QuickScanIncludeExclusions" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisablePackedExeScanning" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8068" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-069" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-069] Configure Scheduled Scan Parameters</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-scheduled-scan-parameters.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Ensuring daily scheduled scans, enabling heuristics for behavioral anomaly detection, scan mail attachments, and forcing a catchup scan after at most 7 days ensures system integrity is continually validated.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Scan</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to run a scheduled scan' to 'Enabled' (Select 'Every day' or '0')</xhtml:li>
            <xhtml:li>Set 'Turn on e-mail scanning' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Turn on heuristics' to 'Enabled'</xhtml:li>
            <xhtml:li>Set 'Trigger a quick scan after X days without any scans' to 'Enabled' (7 days)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderScheduledScan.ps1">Download Script: Configure-DefenderScheduledScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderScheduledScanStatus.ps1">Download Script: Get-DefenderScheduledScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderScheduledScanStatus.ps1
$Pref = Get-MpPreference
$RegDays = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" -Name "DaysWithoutCatchupQuickScan" -ErrorAction SilentlyContinue
if ($Pref.DisableEmailScanning -eq $false -and $Pref.DisableHeuristics -eq $false -and ($RegDays -and $RegDays.DaysWithoutCatchupQuickScan -eq 7)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderScheduledScan.ps1
Set-MpPreference -DisableEmailScanning $false
Set-MpPreference -DisableHeuristics $false
$ScanPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan"
if (-not (Test-Path $ScanPath)) { New-Item -Path $ScanPath -Force | Out-Null }
Set-ItemProperty -Path $ScanPath -Name "ScheduleDay" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableEmailScanning" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DisableHeuristics" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $ScanPath -Name "DaysWithoutCatchupQuickScan" -Value 7 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8069" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-070" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-070] Configure Security Intelligence Update Schedule</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-security-intelligence-update-schedule.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Antivirus signatures must remain fresh to block the latest published threats. Mandating daily checks for updates and marking signatures older than 7 days as out-of-date ensures continuous defense parity.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Security Intelligence Updates</xhtml:li>
            <xhtml:li>Set 'Define the number of days before spyware security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Define the number of days before virus security intelligence is considered out of date' to 'Enabled' (7 days)</xhtml:li>
            <xhtml:li>Set 'Specify the day of the week to check for security intelligence updates' to 'Enabled' (Every day or 0)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderUpdateSchedule.ps1">Download Script: Configure-DefenderUpdateSchedule.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderUpdateScheduleStatus.ps1">Download Script: Get-DefenderUpdateScheduleStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderUpdateScheduleStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ASSignatureDue" -ErrorAction SilentlyContinue
$RegAV = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "AVSignatureDue" -ErrorAction SilentlyContinue
$RegDay = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates" -Name "ScheduleDay" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.ASSignatureDue -eq 7) -and ($RegAV -and $RegAV.AVSignatureDue -eq 7) -and ($RegDay -and $RegDay.ScheduleDay -eq 0)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderUpdateSchedule.ps1
$SigPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Signature Updates"
if (-not (Test-Path $SigPath)) { New-Item -Path $SigPath -Force | Out-Null }
Set-ItemProperty -Path $SigPath -Name "ASSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "AVSignatureDue" -Value 7 -Type DWord -Force
Set-ItemProperty -Path $SigPath -Name "ScheduleDay" -Value 0 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8070" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-072" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-072] Configure Threat Severity Default Quarantine Actions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-threat-severity-default-quarantine-actions.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>By default, Defender may prompt users or take actions (like clean/ignore) that leave malware remnants on the filesystem. Configuring default quarantine actions for all severities (low, medium, high, severe) ensures automated containment.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Threats</xhtml:li>
            <xhtml:li>Set 'Specify threat alert levels at which default action should not be taken when detected' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and enter threat levels (1 -&gt; 2, 2 -&gt; 2, 4 -&gt; 2, 5 -&gt; 2)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderThreatActions.ps1">Download Script: Configure-DefenderThreatActions.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderThreatActionsStatus.ps1">Download Script: Get-DefenderThreatActionsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderThreatActionsStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats" -Name "Threats_ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
$RegSev = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction" -ErrorAction SilentlyContinue
if (($Reg -and $Reg.Threats_ThreatSeverityDefaultAction -eq 1) -and 
    ($RegSev -and $RegSev.1 -eq 2 -and $RegSev.2 -eq 2 -and $RegSev.4 -eq 2 -and $RegSev.5 -eq 2)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderThreatActions.ps1
$ThreatsPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats"
if (-not (Test-Path $ThreatsPath)) { New-Item -Path $ThreatsPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsPath -Name "Threats_ThreatSeverityDefaultAction" -Value 1 -Type DWord -Force
$ThreatsSevPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Threats\ThreatSeverityDefaultAction"
if (-not (Test-Path $ThreatsSevPath)) { New-Item -Path $ThreatsSevPath -Force | Out-Null }
Set-ItemProperty -Path $ThreatsSevPath -Name "1" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "2" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "4" -Value 2 -Type DWord -Force
Set-ItemProperty -Path $ThreatsSevPath -Name "5" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8072" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-073" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-073] Configure Family Options UI Lockdown</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-family-options-ui-lockdown.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Locking down non-essential components of the Windows Security Center interface prevents users from tampering with parental or diagnostic UI controls on enterprise assets.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Family options</xhtml:li>
            <xhtml:li>Set 'Hide the Family options area' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderFamilyLockdown.ps1">Download Script: Configure-DefenderFamilyLockdown.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderFamilyLockdownStatus.ps1">Download Script: Get-DefenderFamilyLockdownStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderFamilyLockdownStatus.ps1
$Reg = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options" -Name "UILockdown" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.UILockdown -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderFamilyLockdown.ps1
$FamilyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Family options"
if (-not (Test-Path $FamilyPath)) { New-Item -Path $FamilyPath -Force | Out-Null }
Set-ItemProperty -Path $FamilyPath -Name "UILockdown" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8073" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-074" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-074] Configure Tamper Protection</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-tamper-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Tamper Protection prevents local administrators or compromised system accounts from disabling Windows Defender services, real-time scanning, or modifying active exclusions locally. This blocks a primary malware persistence vector.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Security\Tamper Protection</xhtml:li>
            <xhtml:li>Set 'Protect Windows Security settings from tampering' to 'Enabled' (Block or On depending on ADMX version)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderTamperProtection.ps1">Download Script: Configure-DefenderTamperProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderTamperProtectionStatus.ps1">Download Script: Get-DefenderTamperProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderTamperProtectionStatus.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
$TamperVal = Get-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -ErrorAction SilentlyContinue
if ($TamperVal -and $TamperVal.TamperProtection -eq 5) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderTamperProtection.ps1
$FeaturesPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features"
if (-not (Test-Path $FeaturesPath)) { New-Item -Path $FeaturesPath -Force | Out-Null }
try {
    Set-ItemProperty -Path $FeaturesPath -Name "TamperProtection" -Value 5 -Type DWord -ErrorAction Stop -Force
} catch {
    Write-Warning "Registry blocked. Tamper Protection registry key is normally protected by TrustedInstaller. Ensure GPO setting is applied."
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8074" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-075" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-075] Configure Sandbox Execution Environment</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-sandbox-execution-environment.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Forcing the Windows Defender scanning service (MsMpEng.exe) to run in a restricted AppContainer sandbox prevents privilege escalation. If an attacker exploits a parsing vulnerability in the engine, the compromise is contained inside the sandbox.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Environment</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Environment Variable</xhtml:li>
            <xhtml:li>Configure Action: Update, Type: System, Name: MP_FORCE_USE_SANDBOX, Value: 1</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderSandbox.ps1">Download Script: Configure-DefenderSandbox.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderSandboxStatus.ps1">Download Script: Get-DefenderSandboxStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderSandboxStatus.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
$SandboxVar = Get-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -ErrorAction SilentlyContinue
if ($SandboxVar -and $SandboxVar.MP_FORCE_USE_SANDBOX -eq "1") {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderSandbox.ps1
$EnvPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if (-not (Test-Path $EnvPath)) { New-Item -Path $EnvPath -Force | Out-Null }
Set-ItemProperty -Path $EnvPath -Name "MP_FORCE_USE_SANDBOX" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8075" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-076" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-076] Configure AMSI Authenticode Signature Verification</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-amsi-authenticode-signature-verification.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing signature checks on registered Antimalware Scan Interface (AMSI) providers blocks attackers from registering unsigned rogue AMSI provider DLLs to bypass script analysis.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Preferences\Windows Settings\Registry</xhtml:li>
            <xhtml:li>Right-click and select New -&gt; Registry Item</xhtml:li>
            <xhtml:li>Configure Action: Update, Hive: HKEY_LOCAL_MACHINE, Key Path: SOFTWARE\Microsoft\AMSI, Value Name: FeatureBits, Value Type: REG_DWORD, Value Data: 2</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderAmsiSignature.ps1">Download Script: Configure-DefenderAmsiSignature.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderAmsiSignatureStatus.ps1">Download Script: Get-DefenderAmsiSignatureStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderAmsiSignatureStatus.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (Test-Path $AmsiPath) {
    $AmsiBits = Get-ItemProperty -Path $AmsiPath -Name "FeatureBits" -ErrorAction SilentlyContinue
    if ($AmsiBits -and $AmsiBits.FeatureBits -eq 2) {
        Write-Output "Compliant"
        exit 0
    }
}
Write-Output "Non-Compliant"
exit 1</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderAmsiSignature.ps1
$AmsiPath = "HKLM:\SOFTWARE\Microsoft\AMSI"
if (-not (Test-Path $AmsiPath)) { New-Item -Path $AmsiPath -Force | Out-Null }
Set-ItemProperty -Path $AmsiPath -Name "FeatureBits" -Value 2 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8076" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-077" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-077] Configure File Explorer SmartScreen</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-file-explorer-smartscreen.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows Defender SmartScreen protects users from running unrecognized or potentially malicious applications downloaded from the internet. Configuring the level to 'Block' prevents users from bypassing security warnings.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\File Explorer</xhtml:li>
            <xhtml:li>Set 'Configure Windows Defender SmartScreen' to 'Enabled'</xhtml:li>
            <xhtml:li>Select 'Require approval from an administrator before running unrecognized software' under Options</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderSmartScreen.ps1">Download Script: Configure-DefenderSmartScreen.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderSmartScreen.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "EnableSmartScreen" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "ShellSmartScreenLevel" -Value "Block" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderSmartScreenStatus.ps1">Download Script: Get-DefenderSmartScreenStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderSmartScreenStatus.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (Test-Path $Path) {
    $Enable = Get-ItemProperty -Path $Path -Name "EnableSmartScreen" -ErrorAction SilentlyContinue
    $Level = Get-ItemProperty -Path $Path -Name "ShellSmartScreenLevel" -ErrorAction SilentlyContinue
    if ($Enable -and $Enable.EnableSmartScreen -eq 1 -and $Level -and $Level.ShellSmartScreenLevel -eq "Block") {
        Write-Output "Compliant"
        exit 0
    }
}
Write-Output "Non-Compliant"
exit 1</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderSmartScreen.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "EnableSmartScreen" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $Path -Name "ShellSmartScreenLevel" -Value "Block" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8077" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-078" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-078] Disable OneDrive File Sync</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/disable-onedrive-file-sync.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Preventing OneDrive files from syncing automatically protects endpoints against automated synchronization of encrypted files during a ransomware event, and prevents unauthorized data exfiltration.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\OneDrive</xhtml:li>
            <xhtml:li>Set 'Prevent the usage of OneDrive for file storage' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableOneDriveSync.ps1">Download Script: Configure-DisableOneDriveSync.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableOneDriveSync.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OneDrive"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableFileSyncNGSC" -Value 1 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DisableOneDriveSyncStatus.ps1">Download Script: Get-DisableOneDriveSyncStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DisableOneDriveSyncStatus.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OneDrive"
$Reg = Get-ItemProperty -Path $Path -Name "DisableFileSyncNGSC" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.DisableFileSyncNGSC -eq 1) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableOneDriveSync.ps1
$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OneDrive"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "DisableFileSyncNGSC" -Value 1 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8078" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-079" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-079] Enforce Antivirus Scan on Opening Attachments</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/enforce-antivirus-scan-on-opening-attachments.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Forcing the Attachment Manager to notify the registered antivirus product when a user opens files downloaded from the web or email clients prevents initial access vectors.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: User Configuration\Administrative Templates\Windows Components\Attachment Manager</xhtml:li>
            <xhtml:li>Set 'Notify antivirus programs when opening attachments' to 'Enabled'</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DefenderAttachmentScan.ps1">Download Script: Configure-DefenderAttachmentScan.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DefenderAttachmentScan.ps1
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "ScanWithAntiVirus" -Value 3 -Type DWord -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-DefenderAttachmentScanStatus.ps1">Download Script: Get-DefenderAttachmentScanStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-DefenderAttachmentScanStatus.ps1
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments"
$Reg = Get-ItemProperty -Path $Path -Name "ScanWithAntiVirus" -ErrorAction SilentlyContinue
if ($Reg -and $Reg.ScanWithAntiVirus -eq 3) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DefenderAttachmentScan.ps1
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments"
if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
Set-ItemProperty -Path $Path -Name "ScanWithAntiVirus" -Value 3 -Type DWord -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8079" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-203" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-203] Configure Remote Encryption Protection Mode</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/configure-remote-encryption-protection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Remote Encryption Protection actively detects and terminates network ransomware attempting to encrypt files over SMB shares. Enforcing Block mode terminates the malicious remote process or connection attempting rapid or unauthorized file encryption over network shares, halting lateral encryption attacks from unmanaged or compromised domain assets.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Defender Antivirus\Remediation\Behavioral Network Blocks\Brute Force Protection</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Configure Remote Encryption Protection Mode</xhtml:strong>.</xhtml:li>
            <xhtml:li>Set the policy to <xhtml:strong>Enabled</xhtml:strong>, and select <xhtml:strong>Block</xhtml:strong> (value <xhtml:code>2</xhtml:code>) in the dropdown options.</xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify replication.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the Remote Encryption Protection registry value:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-RemoteEncryptionProtection.ps1">Download Script: Configure-RemoteEncryptionProtection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-RemoteEncryptionProtection.ps1
# Description: Configures Microsoft Defender Remote Encryption Protection in Block mode.

Write-Host "Configuring Microsoft Defender Remote Encryption Protection..." -ForegroundColor Cyan

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path -Path $KeyPath)) {
    New-Item -Path $KeyPath -Force | Out-Null
}
Set-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -Value 2 -Type DWord -Force

Write-Host "[+] Remote Encryption Protection applied successfully (Block mode)." -ForegroundColor Green</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-RemoteEncryptionProtectionStatus.ps1">Download Script: Get-RemoteEncryptionProtectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-RemoteEncryptionProtectionStatus.ps1
# Description: Audits Microsoft Defender Remote Encryption Protection configuration status.

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
$Reg = Get-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -ErrorAction SilentlyContinue

if ($Reg -and $Reg.BruteForceProtectionConfiguredState -eq 2) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-RemoteEncryptionProtection.ps1
# Description: Configures Microsoft Defender Remote Encryption Protection in Block mode.

Write-Host "Configuring Microsoft Defender Remote Encryption Protection..." -ForegroundColor Cyan

$KeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection"
if (-not (Test-Path -Path $KeyPath)) {
    New-Item -Path $KeyPath -Force | Out-Null
}
Set-ItemProperty -Path $KeyPath -Name "BruteForceProtectionConfiguredState" -Value 2 -Type DWord -Force

Write-Host "[+] Remote Encryption Protection applied successfully (Block mode)." -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8203" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_Attack_Surface_Reduction__ASR__Rules">
      <title>Attack Surface Reduction (ASR) Rules</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-080" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-080] ASR: Block abuse of exploited vulnerable signed drivers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-vulnerable-signed-drivers.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents an application from writing a vulnerable signed driver to disk. Attackers use Bring Your Own Vulnerable Driver (BYOVD) techniques to bypass Windows kernel protections by loading legitimate, signed third-party drivers that contain known vulnerabilities, allowing them to disable security agents and gain kernel-level privileges.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>56a863a9-875e-4185-98a7-b882c64b5ce5</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrVulnerableDrivers.ps1">Download Script: Configure-AsrVulnerableDrivers.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrVulnerableDriversStatus.ps1">Download Script: Get-AsrVulnerableDriversStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrVulnerableDriversStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -ErrorAction SilentlyContinue
if ($Value -and ($Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq "1" -or $Value."56a863a9-875e-4185-98a7-b882c64b5ce5" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrVulnerableDrivers.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "56a863a9-875e-4185-98a7-b882c64b5ce5" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8080" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-081" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-081] ASR: Block Adobe Reader from creating child processes</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-adobe-reader-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents Adobe Reader from launching any child processes. Malicious PDF documents frequently attempt to exploit application vulnerabilities or trick users into executing embedded links, which spawns command shells (cmd.exe, powershell.exe) or scripting hosts (wscript.exe) to download and launch secondary malware payloads.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrAdobeChild.ps1">Download Script: Configure-AsrAdobeChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrAdobeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrAdobeChildStatus.ps1">Download Script: Get-AsrAdobeChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrAdobeChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -ErrorAction SilentlyContinue
if ($Value -and ($Value."7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -eq "1" -or $Value."7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrAdobeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8081" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-082" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-082] ASR: Block all Office applications from creating child processes</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-office-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Office applications (Word, Excel, PowerPoint) from creating child processes. This prevents malicious files containing embedded VBA macros or exploiting unpatched vulnerabilities (such as CVE-2021-40444) from launching scripting environments or system commands to download and execute code.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d4f940ab-401b-4efc-aadc-ad5f3c50688a</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrOfficeChild.ps1">Download Script: Configure-AsrOfficeChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrOfficeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrOfficeChildStatus.ps1">Download Script: Get-AsrOfficeChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrOfficeChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d4f940ab-401b-4efc-aadc-ad5f3c50688a" -eq "1" -or $Value."d4f940ab-401b-4efc-aadc-ad5f3c50688a" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrOfficeChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8082" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-083" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-083] ASR: Block credential stealing from the Windows local security authority subsystem</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-lsass-credential-stealing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks attempts to open or dump the memory of the Local Security Authority Subsystem Service (lsass.exe). Attackers dump LSASS memory using tools like Mimikatz or Task Manager to extract plaintext credentials, Kerberos tickets, or NTLM password hashes from system memory for lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrLsassDump.ps1">Download Script: Configure-AsrLsassDump.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrLsassDumpStatus.ps1">Download Script: Get-AsrLsassDumpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrLsassDumpStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -ErrorAction SilentlyContinue
if ($Value -and ($Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq "1" -or $Value."9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrLsassDump.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8083" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-084" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-084] ASR: Block executable content from email client and webmail</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-email-executable-content.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents executable files (such as .exe, .com, .scr, .vbs, .js, or .pif) from launching directly from email clients (like Outlook) or webmail accessed via browser sessions. This stops phishing attacks where users accidentally launch malicious attachments or download payloads directly from web-based email links.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>be9ba2d9-53ea-4cdc-84e5-9b1eeee46550</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrEmailExecutable.ps1">Download Script: Configure-AsrEmailExecutable.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrEmailExecutable.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrEmailExecutableStatus.ps1">Download Script: Get-AsrEmailExecutableStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrEmailExecutableStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -ErrorAction SilentlyContinue
if ($Value -and ($Value."be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -eq "1" -or $Value."be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrEmailExecutable.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8084" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-085" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-085] ASR: Block executable files from running unless they meet a prevalence, age, or trusted list criterion</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-low-prevalence-executable-files.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks execution of unrecognized, newly compiled, or low-prevalence executable files. This provides initial protection against zero-day malware campaigns and targeted custom payloads that have not yet established reputation telemetry in the Microsoft Cloud Protection network.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>01443614-cd74-433a-b99e-2ecdc07bfc25</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrLowPrevalence.ps1">Download Script: Configure-AsrLowPrevalence.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrLowPrevalence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrLowPrevalenceStatus.ps1">Download Script: Get-AsrLowPrevalenceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrLowPrevalenceStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -ErrorAction SilentlyContinue
if ($Value -and ($Value."01443614-cd74-433a-b99e-2ecdc07bfc25" -eq "1" -or $Value."01443614-cd74-433a-b99e-2ecdc07bfc25" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrLowPrevalence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "01443614-cd74-433a-b99e-2ecdc07bfc25" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8085" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-086" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-086] ASR: Block execution of potentially obfuscated scripts</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-obfuscated-scripts.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks execution of obfuscated or encrypted scripts (such as PowerShell, VBScript, or JavaScript). Threat actors obfuscate their scripts using base64 encoding, custom string manipulation, or encryption to hide the intent of their code and bypass static file scanning and network detection engines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>5beb7efe-fd9a-4556-801d-275e5ffc04cc</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrObfuscatedScripts.ps1">Download Script: Configure-AsrObfuscatedScripts.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrObfuscatedScriptsStatus.ps1">Download Script: Get-AsrObfuscatedScriptsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrObfuscatedScriptsStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -ErrorAction SilentlyContinue
if ($Value -and ($Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq "1" -or $Value."5beb7efe-fd9a-4556-801d-275e5ffc04cc" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrObfuscatedScripts.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "5beb7efe-fd9a-4556-801d-275e5ffc04cc" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8086" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-087" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-087] ASR: Block JavaScript or VBScript from launching downloaded executable content</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-script-launching-downloaded-content.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents JavaScript or VBScript running locally from launching executable binaries that were downloaded from the internet. Attackers use malicious scripts inside documents or web browsers to download payloads (like ransomware or trojans) to the disk and launch them using local script engines.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d3e037e1-3eb8-44c8-a917-57927947596d</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrScriptLaunchExe.ps1">Download Script: Configure-AsrScriptLaunchExe.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrScriptLaunchExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrScriptLaunchExeStatus.ps1">Download Script: Get-AsrScriptLaunchExeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrScriptLaunchExeStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d3e037e1-3eb8-44c8-a917-57927947596d" -eq "1" -or $Value."d3e037e1-3eb8-44c8-a917-57927947596d" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrScriptLaunchExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d3e037e1-3eb8-44c8-a917-57927947596d" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8087" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-088" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-088] ASR: Block Office applications from creating executable content</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-office-executable-content-creation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Prevents Microsoft Office applications (Word, Excel, PowerPoint) from creating or writing executable files (e.g., .exe, .dll, .scr) to the local filesystem. Malicious documents often attempt to drop payloads directly into the local temp folders or AppData directories before executing them.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>3b576869-a4ec-4529-8536-b80a7769e899</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrOfficeWriteExe.ps1">Download Script: Configure-AsrOfficeWriteExe.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrOfficeWriteExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrOfficeWriteExeStatus.ps1">Download Script: Get-AsrOfficeWriteExeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrOfficeWriteExeStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -ErrorAction SilentlyContinue
if ($Value -and ($Value."3b576869-a4ec-4529-8536-b80a7769e899" -eq "1" -or $Value."3b576869-a4ec-4529-8536-b80a7769e899" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrOfficeWriteExe.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "3b576869-a4ec-4529-8536-b80a7769e899" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8088" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-089" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-089] ASR: Block Office applications from injecting code into other processes</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-office-code-injection.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Office applications from writing code or injecting threads directly into external processes. Threat actors use code injection (such as process hollowing or remote thread creation) inside Office macros to hide execution under clean, trusted system binaries like explorer.exe or svchost.exe.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrOfficeInjection.ps1">Download Script: Configure-AsrOfficeInjection.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrOfficeInjection.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrOfficeInjectionStatus.ps1">Download Script: Get-AsrOfficeInjectionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrOfficeInjectionStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -ErrorAction SilentlyContinue
if ($Value -and ($Value."75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -eq "1" -or $Value."75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrOfficeInjection.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8089" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-090" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-090] ASR: Block Office communication application from creating child processes</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-office-communication-child-processes.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks Microsoft Outlook or other Office communication applications (e.g., Teams, Skype) from creating child processes. This prevents malware payloads delivered through emails, chats, or calendar invites from spawning command-line utilities or scripting environments.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>26190899-1602-49e8-8b27-eb1d0a1ce869</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrOutlookChild.ps1">Download Script: Configure-AsrOutlookChild.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrOutlookChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrOutlookChildStatus.ps1">Download Script: Get-AsrOutlookChildStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrOutlookChildStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -ErrorAction SilentlyContinue
if ($Value -and ($Value."26190899-1602-49e8-8b27-eb1d0a1ce869" -eq "1" -or $Value."26190899-1602-49e8-8b27-eb1d0a1ce869" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrOutlookChild.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8090" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-091" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-091] ASR: Block persistence through WMI event subscription</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-wmi-event-subscription-persistence.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks threat actors from achieving system persistence by registering permanent Windows Management Instrumentation (WMI) event subscriptions. WMI event subscriptions allow attackers to automatically launch malicious payloads when system triggers occur (like system boot or user logon) without using traditional startup registry keys.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>e6db77e5-3df2-4cf1-b95a-636979351e5b</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrWmiPersistence.ps1">Download Script: Configure-AsrWmiPersistence.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrWmiPersistenceStatus.ps1">Download Script: Get-AsrWmiPersistenceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrWmiPersistenceStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -ErrorAction SilentlyContinue
if ($Value -and ($Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq "1" -or $Value."e6db77e5-3df2-4cf1-b95a-636979351e5b" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrWmiPersistence.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "e6db77e5-3df2-4cf1-b95a-636979351e5b" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8091" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-092" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-092] ASR: Block process creations originating from PSExec and WMI commands</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-psexec-wmi-process-creations.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks processes created via WMI commands or PSExec remote execution utilities. This directly stops lateral movement attacks where compromised accounts or threat actors attempt to start commands, backdoors, or credential dumpers remotely across domain-joined servers and workstations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>d1e49aac-8f56-4280-b9ba-993a6d77406c</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrPsexecWmi.ps1">Download Script: Configure-AsrPsexecWmi.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrPsexecWmiStatus.ps1">Download Script: Get-AsrPsexecWmiStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrPsexecWmiStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -ErrorAction SilentlyContinue
if ($Value -and ($Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq "1" -or $Value."d1e49aac-8f56-4280-b9ba-993a6d77406c" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrPsexecWmi.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "d1e49aac-8f56-4280-b9ba-993a6d77406c" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8092" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-093" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-093] ASR: Block untrusted and unsigned processes that run from USB</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-unsigned-processes-running-from-usb.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks the execution of unsigned or untrusted processes on removable storage devices (USB drives, external SSDs). This stops physical access vectors, rogue USB drops, and automated worm propagation techniques from running unauthorized installers or scripts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrUsbUnsigned.ps1">Download Script: Configure-AsrUsbUnsigned.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrUsbUnsigned.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrUsbUnsignedStatus.ps1">Download Script: Get-AsrUsbUnsignedStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrUsbUnsignedStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -ErrorAction SilentlyContinue
if ($Value -and ($Value."b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -eq "1" -or $Value."b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrUsbUnsigned.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8093" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-094" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-094] ASR: Block Win32 API calls from Office macros</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/block-win32-api-calls-from-office-macros.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Blocks VBA macros inside Microsoft Office documents from invoking Win32 API calls. Malicious documents use macros to call kernel memory functions (such as VirtualAlloc, WriteProcessMemory, or CreateThread) to load and execute shellcode in memory without dropping files to disk, bypassing file scanners.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrOfficeWin32Calls.ps1">Download Script: Configure-AsrOfficeWin32Calls.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrOfficeWin32Calls.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrOfficeWin32CallsStatus.ps1">Download Script: Get-AsrOfficeWin32CallsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrOfficeWin32CallsStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -ErrorAction SilentlyContinue
if ($Value -and ($Value."92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -eq "1" -or $Value."92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrOfficeWin32Calls.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8094" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-095" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-095] ASR: Use advanced protection against ransomware</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (and above) Enterprise/Professional, Windows Server 2016 (and above).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/defender/asr/use-advanced-protection-against-ransomware.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enables advanced behavioral heuristics and cloud analytics checks on files that attempt to modify multiple user files, detect signature-less encryption behavior, and block rapid write activity to prevent ransomware from encrypting system and user documents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Navigate to: Computer Configuration\Administrative Templates\Windows Components\Windows Defender Antivirus\Windows Defender Exploit Guard\Attack Surface Reduction</xhtml:li>
            <xhtml:li>Set 'Configure Attack Surface Reduction rules' to 'Enabled'</xhtml:li>
            <xhtml:li>Click 'Show...' and add the rule GUID <xhtml:code>c1db55ab-c21a-4637-bb3f-a12568109d35</xhtml:code> as Value Name, with Value set to <xhtml:code>1</xhtml:code> (Block).</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../../implementation_scripts/Configure-AsrRansomware.ps1">Download Script: Configure-AsrRansomware.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-AsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../../audit_scripts/Get-AsrRansomwareStatus.ps1">Download Script: Get-AsrRansomwareStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-AsrRansomwareStatus.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
$Value = Get-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -ErrorAction SilentlyContinue
if ($Value -and ($Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq "1" -or $Value."c1db55ab-c21a-4637-bb3f-a12568109d35" -eq 1)) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-AsrRansomware.ps1
$AsrRulesPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules"
if (-not (Test-Path $AsrRulesPath)) { New-Item -Path $AsrRulesPath -Force | Out-Null }
Set-ItemProperty -Path $AsrRulesPath -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" -Value "1" -Type String -Force</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8095" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_User_Rights_Assignments">
      <title>User Rights Assignments</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-096" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-096] Configure User Rights: Access Credential Manager as a trusted caller</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-092](../../07-paws/user-rights/configure-ura-setrustedcredmanaccessprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-setrustedcredmanaccessprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTrustedCredManAccessPrivilege</xhtml:code> allows a process to access the Windows Credential Manager as a trusted caller via internal Credential Manager APIs. The Credential Manager securely stores user domain credentials, web passwords, and certificate secrets used for network authentication.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Access Credential Manager as a trusted caller`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeTrustedCredManAccessPrivilege.ps1">Download Script: Configure-UraSeTrustedCredManAccessPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeTrustedCredManAccessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setrustedcredmanaccessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setrustedcredmanaccessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTrustedCredManAccessPrivilege\s*=") {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTrustedCredManAccessPrivilege = ")
    } else {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeTrustedCredManAccessPrivilegeStatus.ps1">Download Script: Get-UraSeTrustedCredManAccessPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeTrustedCredManAccessPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setrustedcredmanaccessprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTrustedCredManAccessPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeTrustedCredManAccessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setrustedcredmanaccessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setrustedcredmanaccessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTrustedCredManAccessPrivilege\s*=") {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTrustedCredManAccessPrivilege = ")
    } else {
        $NewLines += "SeTrustedCredManAccessPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8096" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-097" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-097] Configure User Rights: Access this computer from the network</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-093](../../07-paws/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-104](../../02-domain-controllers/user-rights/configure-ura-senetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-senetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeNetworkLogonRight</xhtml:code> determines which security principals are permitted to authenticate and establish network logon sessions (Logon Type 3) across the network over protocols like SMB, RPC, WMI, WinRM, and LDAP. Network logons authenticate users without creating an interactive desktop shell, enabling file share access, remote management, and inter-system synchronization.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Access this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-32-555 (Remote Desktop Users)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeNetworkLogonRight.ps1">Download Script: Configure-UraSeNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeNetworkLogonRightStatus.ps1">Download Script: Get-UraSeNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_senetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-32-555"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_senetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_senetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeNetworkLogonRight\s*=") {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555")
    } else {
        $NewLines += "SeNetworkLogonRight = *S-1-5-32-544,*S-1-5-32-555"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8097" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-098" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-098] Configure User Rights: Act as part of the operating system</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-094](../../07-paws/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-105](../../02-domain-controllers/user-rights/configure-ura-setcbprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-setcbprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTcbPrivilege</xhtml:code> identifies its holder as part of the Trusted Computer Base (TCB)—the core inner ring of the operating system. A process possessing this privilege can register as a trusted logon process with the Local Security Authority via <xhtml:code>LsaRegisterLogonProcess</xhtml:code> and invoke <xhtml:code>LsaLogonUser</xhtml:code> to create an arbitrary, fully authenticated access token for any user without knowing the user's password or requiring credentials.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Act as part of the operating system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeTcbPrivilege.ps1">Download Script: Configure-UraSeTcbPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeTcbPrivilegeStatus.ps1">Download Script: Get-UraSeTcbPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeTcbPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setcbprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTcbPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeTcbPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setcbprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setcbprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTcbPrivilege\s*=") {
        $NewLines += "SeTcbPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTcbPrivilege = ")
    } else {
        $NewLines += "SeTcbPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8098" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-099" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-099] Configure User Rights: Allow log on locally</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-095](../../07-paws/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-108](../../02-domain-controllers/user-rights/configure-ura-seinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeInteractiveLogonRight</xhtml:code> determines which security principals are permitted to start an interactive logon session (Logon Type 2) at the physical keyboard, display, or virtual machine console. An interactive logon spawns a graphical user shell (<xhtml:code>explorer.exe</xhtml:code>) and interactive desktop session.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Allow log on locally`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-32-545 (Users)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeInteractiveLogonRight.ps1">Download Script: Configure-UraSeInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeInteractiveLogonRightStatus.ps1">Download Script: Get-UraSeInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-32-545"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeInteractiveLogonRight\s*=") {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545")
    } else {
        $NewLines += "SeInteractiveLogonRight = *S-1-5-32-544,*S-1-5-32-545"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8099" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-100" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-100] Configure User Rights: Back up files and directories</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-096](../../07-paws/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-110](../../02-domain-controllers/user-rights/configure-ura-sebackupprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sebackupprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeBackupPrivilege</xhtml:code> grants the caller the capability to bypass all read-access security controls (Discretionary Access Control Lists - DACLs) across the entire NTFS filesystem and Windows Registry. When an application opens a file handle specifying the <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> flag in Win32 <xhtml:code>CreateFile</xhtml:code> calls, the Windows kernel I/O manager and Object Manager explicitly bypass standard security descriptor evaluation. This design allows legitimate backup utilities to archive files without requiring explicit read permissions on every individual object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Back up files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeBackupPrivilege.ps1">Download Script: Configure-UraSeBackupPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeBackupPrivilegeStatus.ps1">Download Script: Get-UraSeBackupPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeBackupPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sebackupprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeBackupPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeBackupPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sebackupprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sebackupprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeBackupPrivilege\s*=") {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeBackupPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeBackupPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8100" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-101" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-101] Configure User Rights: Change the system time</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Domain Controllers, refer to [REQ-DC-112](../../02-domain-controllers/user-rights/configure-ura-sesystemtimeprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sesystemtimeprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemtimePrivilege</xhtml:code> allows a security principal to adjust the internal hardware clock and system time of the computer via Win32 APIs <xhtml:code>SetSystemTime</xhtml:code> or <xhtml:code>SetLocalTime</xhtml:code>. Accurate time synchronization is foundational to the Windows distributed security architecture.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Change the system time`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-19 (LocalService)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeSystemtimePrivilege.ps1">Download Script: Configure-UraSeSystemtimePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeSystemtimePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemtimeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemtimeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemtimePrivilege\s*=") {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19")
    } else {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeSystemtimePrivilegeStatus.ps1">Download Script: Get-UraSeSystemtimePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeSystemtimePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemtimeprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemtimePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-19"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeSystemtimePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemtimeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemtimeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemtimePrivilege\s*=") {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19")
    } else {
        $NewLines += "SeSystemtimePrivilege = *S-1-5-32-544,*S-1-5-19"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8101" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-102" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-102] Configure User Rights: Change the time zone</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-setimezoneprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTimeZonePrivilege</xhtml:code> controls the capability to change the system local time zone setting via <xhtml:code>SetTimeZoneInformation</xhtml:code>. While changing the time zone does not alter the underlying UTC hardware clock, it alters the local display time and timestamp calculations across the operating system.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Change the time zone`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-19 (LocalService), *S-1-5-32-545 (Users)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeTimeZonePrivilege.ps1">Download Script: Configure-UraSeTimeZonePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeTimeZonePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setimezoneprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setimezoneprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTimeZonePrivilege\s*=") {
        $NewLines += "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545")
    } else {
        $NewLines += "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeTimeZonePrivilegeStatus.ps1">Download Script: Get-UraSeTimeZonePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeTimeZonePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setimezoneprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTimeZonePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-19,*S-1-5-32-545"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeTimeZonePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setimezoneprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setimezoneprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTimeZonePrivilege\s*=") {
        $NewLines += "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545")
    } else {
        $NewLines += "SeTimeZonePrivilege = *S-1-5-32-544,*S-1-5-19,*S-1-5-32-545"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8102" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-103" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-103] Configure User Rights: Create a pagefile</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-097](../../07-paws/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-113](../../02-domain-controllers/user-rights/configure-ura-secreatepagefileprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-secreatepagefileprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePagefilePrivilege</xhtml:code> allows a process to create, delete, and modify the parameters and allocation sizes of system paging files (<xhtml:code>pagefile.sys</xhtml:code>) via the <xhtml:code>NtCreatePagingFile</xhtml:code> API. The Windows virtual memory manager uses paging files as secondary backing storage for memory pages that are not backed by files. Paging files contain sensitive plaintext data, including process heap allocations, cached authentication tokens, cryptographic keys, and unencrypted file contents.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a pagefile`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeCreatePagefilePrivilege.ps1">Download Script: Configure-UraSeCreatePagefilePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeCreatePagefilePrivilegeStatus.ps1">Download Script: Get-UraSeCreatePagefilePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeCreatePagefilePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepagefileprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePagefilePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeCreatePagefilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepagefileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepagefileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePagefilePrivilege\s*=") {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePagefilePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreatePagefilePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8103" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-104" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-104] Configure User Rights: Create a token object</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-098](../../07-paws/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-114](../../02-domain-controllers/user-rights/configure-ura-secreatetokenprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-secreatetokenprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateTokenPrivilege</xhtml:code> allows a process to invoke the native API <xhtml:code>NtCreateToken</xhtml:code> to forge an arbitrary Windows primary or impersonation access token from scratch. An access token defines an entity's complete security context, including User SID, Group SIDs, Privileges, Default DACL, Token Type, and Mandatory Integrity Level. Normally, tokens are manufactured exclusively by the Local Security Authority Subsystem Service (<xhtml:code>lsass.exe</xhtml:code>) following successful authentication.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create a token object`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeCreateTokenPrivilege.ps1">Download Script: Configure-UraSeCreateTokenPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeCreateTokenPrivilegeStatus.ps1">Download Script: Get-UraSeCreateTokenPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeCreateTokenPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatetokenprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateTokenPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeCreateTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatetokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatetokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateTokenPrivilege\s*=") {
        $NewLines += "SeCreateTokenPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateTokenPrivilege = ")
    } else {
        $NewLines += "SeCreateTokenPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8104" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-105" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-105] Configure User Rights: Create global objects</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-099](../../07-paws/user-rights/configure-ura-secreateglobalprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-secreateglobalprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateGlobalPrivilege</xhtml:code> allows a process to create named kernel and user objects (such as named pipes, shared memory sections, mutexes, and events) in the <xhtml:code>\BaseNamedObjects</xhtml:code> global namespace accessible across all terminal services sessions and interactive logon sessions. In terminal services and multi-user Windows environments, each interactive session is isolated into a private namespace (<xhtml:code>\Sessions\X\BaseNamedObjects</xhtml:code>). The global namespace is reserved for system services that must communicate across session boundaries.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create global objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService), *S-1-5-32-544 (Administrators), *S-1-5-6 (Service)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeCreateGlobalPrivilege.ps1">Download Script: Configure-UraSeCreateGlobalPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeCreateGlobalPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreateglobalprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreateglobalprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateGlobalPrivilege\s*=") {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeCreateGlobalPrivilegeStatus.ps1">Download Script: Get-UraSeCreateGlobalPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeCreateGlobalPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreateglobalprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateGlobalPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeCreateGlobalPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreateglobalprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreateglobalprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateGlobalPrivilege\s*=") {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeCreateGlobalPrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8105" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-106" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-106] Configure User Rights: Create permanent shared objects</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-100](../../07-paws/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-115](../../02-domain-controllers/user-rights/configure-ura-secreatepermanentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-secreatepermanentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreatePermanentPrivilege</xhtml:code> allows a process to create permanent object directory objects in the Windows Object Manager namespace (<xhtml:code>\DirectoryObject</xhtml:code>) via APIs like <xhtml:code>NtCreateDirectoryObject</xhtml:code>. Unlike standard kernel objects which are automatically destroyed when their last handle is closed, permanent objects persist in the object manager namespace across process terminations until explicitly unlinked or until system reboot.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create permanent shared objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeCreatePermanentPrivilege.ps1">Download Script: Configure-UraSeCreatePermanentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeCreatePermanentPrivilegeStatus.ps1">Download Script: Get-UraSeCreatePermanentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeCreatePermanentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatepermanentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreatePermanentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeCreatePermanentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatepermanentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatepermanentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreatePermanentPrivilege\s*=") {
        $NewLines += "SeCreatePermanentPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreatePermanentPrivilege = ")
    } else {
        $NewLines += "SeCreatePermanentPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8106" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-107" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-107] Configure User Rights: Create symbolic links</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-secreatesymboliclinkprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeCreateSymbolicLinkPrivilege</xhtml:code> controls the ability to create filesystem symbolic links (symlinks) via <xhtml:code>CreateSymbolicLink</xhtml:code> or <xhtml:code>mklink</xhtml:code>. Symbolic links are filesystem pointers that transparently redirect file and directory access to alternate target paths. While useful for software development and container workflows, unconstrained symbolic link creation represents one of the most common primitives for Local Privilege Escalation (LPE) in Windows.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Create symbolic links`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeCreateSymbolicLinkPrivilege.ps1">Download Script: Configure-UraSeCreateSymbolicLinkPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeCreateSymbolicLinkPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatesymboliclinkprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatesymboliclinkprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateSymbolicLinkPrivilege\s*=") {
        $NewLines += "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeCreateSymbolicLinkPrivilegeStatus.ps1">Download Script: Get-UraSeCreateSymbolicLinkPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeCreateSymbolicLinkPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_secreatesymboliclinkprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeCreateSymbolicLinkPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeCreateSymbolicLinkPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_secreatesymboliclinkprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_secreatesymboliclinkprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeCreateSymbolicLinkPrivilege\s*=") {
        $NewLines += "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeCreateSymbolicLinkPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8107" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-108" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-108] Configure User Rights: Debug programs</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-101](../../07-paws/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-116](../../02-domain-controllers/user-rights/configure-ura-sedebugprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sedebugprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDebugPrivilege</xhtml:code> allows a process to attach a debugger to any running process on the system, completely overriding the target process security descriptor and Discretionary Access Control List (DACL). When enabled, calls to <xhtml:code>OpenProcess</xhtml:code> with permissions such as <xhtml:code>PROCESS_ALL_ACCESS</xhtml:code> or <xhtml:code>PROCESS_VM_READ</xhtml:code> succeed even against processes owned by other users or <xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>. This privilege is intended strictly for kernel/application developers debugging live processes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Debug programs`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeDebugPrivilege.ps1">Download Script: Configure-UraSeDebugPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeDebugPrivilegeStatus.ps1">Download Script: Get-UraSeDebugPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeDebugPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedebugprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDebugPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeDebugPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedebugprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedebugprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDebugPrivilege\s*=") {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDebugPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeDebugPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8108" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-109" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-109] Configure User Rights: Enable computer and user accounts to be trusted for delegation</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-102](../../07-paws/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-122](../../02-domain-controllers/user-rights/configure-ura-seenabledelegationprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seenabledelegationprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeEnableDelegationPrivilege</xhtml:code> allows a security principal to modify the <xhtml:code>userAccountControl</xhtml:code> attribute on Active Directory user and computer objects to enable Kerberos Delegation flags: (1) <xhtml:code>TRUSTED_FOR_DELEGATION</xhtml:code> (Unconstrained Delegation); (2) <xhtml:code>TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION</xhtml:code> (Constrained Delegation with Protocol Transition / S4U2Self). Kerberos delegation permits a service to impersonate an authenticated user to access back-end resources on their behalf.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Enable computer and user accounts to be trusted for delegation`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeEnableDelegationPrivilege.ps1">Download Script: Configure-UraSeEnableDelegationPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = ")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeEnableDelegationPrivilegeStatus.ps1">Download Script: Get-UraSeEnableDelegationPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeEnableDelegationPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seenabledelegationprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeEnableDelegationPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeEnableDelegationPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seenabledelegationprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seenabledelegationprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeEnableDelegationPrivilege\s*=") {
        $NewLines += "SeEnableDelegationPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeEnableDelegationPrivilege = ")
    } else {
        $NewLines += "SeEnableDelegationPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8109" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-110" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-110] Configure User Rights: Force shutdown from a remote system</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-103](../../07-paws/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-123](../../02-domain-controllers/user-rights/configure-ura-seremoteshutdownprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seremoteshutdownprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRemoteShutdownPrivilege</xhtml:code> allows a user authenticating over the network to invoke remote system shutdown and reboot APIs (such as <xhtml:code>InitiateSystemShutdownEx</xhtml:code> or <xhtml:code>shutdown.exe /m \\computer</xhtml:code>). This function is exposed over named pipe <xhtml:code>\PIPE\InitShutdown</xhtml:code> and RPC interface <xhtml:code>winreg</xhtml:code>/<xhtml:code>shutdown</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Force shutdown from a remote system`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeRemoteShutdownPrivilege.ps1">Download Script: Configure-UraSeRemoteShutdownPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeRemoteShutdownPrivilegeStatus.ps1">Download Script: Get-UraSeRemoteShutdownPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeRemoteShutdownPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seremoteshutdownprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRemoteShutdownPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeRemoteShutdownPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seremoteshutdownprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seremoteshutdownprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRemoteShutdownPrivilege\s*=") {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRemoteShutdownPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRemoteShutdownPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8110" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-111" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-111] Configure User Rights: Impersonate a client after authentication</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-104](../../07-paws/user-rights/configure-ura-seimpersonateprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seimpersonateprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeImpersonatePrivilege</xhtml:code> grants a program the ability to impersonate a client that has connected to its local RPC interfaces, named pipes, or COM servers via <xhtml:code>ImpersonateNamedPipeClient</xhtml:code>, <xhtml:code>CoImpersonateClient</xhtml:code>, or <xhtml:code>RpcImpersonateClient</xhtml:code>. Impersonation allows a server process to temporarily run in the security context of the calling client to verify access permissions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Impersonate a client after authentication`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService), *S-1-5-32-544 (Administrators), *S-1-5-6 (Service)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeImpersonatePrivilege.ps1">Download Script: Configure-UraSeImpersonatePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeImpersonatePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seimpersonateprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seimpersonateprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeImpersonatePrivilege\s*=") {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeImpersonatePrivilegeStatus.ps1">Download Script: Get-UraSeImpersonatePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeImpersonatePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seimpersonateprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeImpersonatePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeImpersonatePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seimpersonateprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seimpersonateprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeImpersonatePrivilege\s*=") {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6")
    } else {
        $NewLines += "SeImpersonatePrivilege = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8111" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-112" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-112] Configure User Rights: Increase scheduling priority</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seincreasebasepriorityprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeIncreaseBasePriorityPrivilege</xhtml:code> allows a process to raise the execution priority class of a process or thread via <xhtml:code>SetPriorityClass</xhtml:code> to <xhtml:code>REALTIME_PRIORITY_CLASS</xhtml:code>. The Windows kernel thread scheduler gives realtime priority threads preemption authority over virtually all other system threads, including device driver deferred procedure calls (DPCs) and operating system subsystem threads.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Increase scheduling priority`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-90-0 (Window Manager Group)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeIncreaseBasePriorityPrivilege.ps1">Download Script: Configure-UraSeIncreaseBasePriorityPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeIncreaseBasePriorityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seincreasebasepriorityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seincreasebasepriorityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeIncreaseBasePriorityPrivilege\s*=") {
        $NewLines += "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0")
    } else {
        $NewLines += "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeIncreaseBasePriorityPrivilegeStatus.ps1">Download Script: Get-UraSeIncreaseBasePriorityPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeIncreaseBasePriorityPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seincreasebasepriorityprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeIncreaseBasePriorityPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-90-0"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeIncreaseBasePriorityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seincreasebasepriorityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seincreasebasepriorityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeIncreaseBasePriorityPrivilege\s*=") {
        $NewLines += "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0")
    } else {
        $NewLines += "SeIncreaseBasePriorityPrivilege = *S-1-5-32-544,*S-1-5-90-0"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8112" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-113" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-113] Configure User Rights: Load and unload device drivers</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-105](../../07-paws/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-125](../../02-domain-controllers/user-rights/configure-ura-seloaddriverprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seloaddriverprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLoadDriverPrivilege</xhtml:code> allows a process to dynamically load and unload kernel-mode device drivers (<xhtml:code>.sys</xhtml:code> files) via <xhtml:code>NtLoadDriver</xhtml:code> or the Service Control Manager (<xhtml:code>CreateService</xhtml:code> with <xhtml:code>SERVICE_KERNEL_DRIVER</xhtml:code>). Kernel-mode drivers execute in Ring 0 with unrestricted hardware access, full kernel memory read/write permissions, and the ability to execute any CPU instruction.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Load and unload device drivers`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeLoadDriverPrivilege.ps1">Download Script: Configure-UraSeLoadDriverPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeLoadDriverPrivilegeStatus.ps1">Download Script: Get-UraSeLoadDriverPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeLoadDriverPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seloaddriverprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLoadDriverPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeLoadDriverPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seloaddriverprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seloaddriverprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLoadDriverPrivilege\s*=") {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLoadDriverPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeLoadDriverPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8113" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-114" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-114] Configure User Rights: Lock pages in memory</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-106](../../07-paws/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-126](../../02-domain-controllers/user-rights/configure-ura-selockmemoryprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-selockmemoryprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeLockMemoryPrivilege</xhtml:code> allows a process to lock physical memory pages in RAM using APIs such as <xhtml:code>VirtualLock</xhtml:code> and Address Windowing Extensions (AWE) via <xhtml:code>AllocateUserPhysicalPages</xhtml:code>. Locking pages prevents the Windows virtual memory manager from paging data out to disk in <xhtml:code>pagefile.sys</xhtml:code>, ensuring high-performance memory retention.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Lock pages in memory`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeLockMemoryPrivilege.ps1">Download Script: Configure-UraSeLockMemoryPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeLockMemoryPrivilegeStatus.ps1">Download Script: Get-UraSeLockMemoryPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeLockMemoryPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_selockmemoryprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeLockMemoryPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeLockMemoryPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_selockmemoryprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_selockmemoryprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeLockMemoryPrivilege\s*=") {
        $NewLines += "SeLockMemoryPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeLockMemoryPrivilege = ")
    } else {
        $NewLines += "SeLockMemoryPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8114" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-115" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-115] Configure User Rights: Manage auditing and security log</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-107](../../07-paws/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-129](../../02-domain-controllers/user-rights/configure-ura-sesecurityprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sesecurityprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSecurityPrivilege</xhtml:code> controls access to the Windows Security Event Log (<xhtml:code>Security.evtx</xhtml:code>) and governs the ability to view, configure, and clear the security log, as well as specify object auditing options (System Access Control Lists - SACLs) on files, registry keys, and directory objects via <xhtml:code>ACCESS_SYSTEM_SECURITY</xhtml:code>.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Manage auditing and security log`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeSecurityPrivilege.ps1">Download Script: Configure-UraSeSecurityPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeSecurityPrivilegeStatus.ps1">Download Script: Get-UraSeSecurityPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeSecurityPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesecurityprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSecurityPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeSecurityPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesecurityprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesecurityprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSecurityPrivilege\s*=") {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSecurityPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSecurityPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8115" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-116" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-116] Configure User Rights: Modify firmware environment values</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-108](../../07-paws/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-130](../../02-domain-controllers/user-rights/configure-ura-sesystemenvironmentprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sesystemenvironmentprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemEnvironmentPrivilege</xhtml:code> allows a process to query and modify Non-Volatile RAM (NVRAM) firmware environment variables via Win32 APIs <xhtml:code>GetFirmwareEnvironmentVariable</xhtml:code> and <xhtml:code>SetFirmwareEnvironmentVariable</xhtml:code>. NVRAM variables govern UEFI boot sequences, Secure Boot policies, boot configuration data (BCD) handoffs, and hardware configuration flags.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Modify firmware environment values`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeSystemEnvironmentPrivilege.ps1">Download Script: Configure-UraSeSystemEnvironmentPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeSystemEnvironmentPrivilegeStatus.ps1">Download Script: Get-UraSeSystemEnvironmentPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeSystemEnvironmentPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemenvironmentprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemEnvironmentPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeSystemEnvironmentPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemenvironmentprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemenvironmentprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemEnvironmentPrivilege\s*=") {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemEnvironmentPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeSystemEnvironmentPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8116" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-117" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-117] Configure User Rights: Perform volume maintenance tasks</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-109](../../07-paws/user-rights/configure-ura-semanagevolumeprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-semanagevolumeprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeManageVolumePrivilege</xhtml:code> allows a process to perform low-level disk and volume maintenance tasks, including running defragmentation tools, modifying volume quotas, and invoking the <xhtml:code>SetFileValidData</xhtml:code> Win32 API. The <xhtml:code>SetFileValidData</xhtml:code> function allows a caller to extend the valid data length of an allocated file without zeroing out the intervening disk clusters.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Perform volume maintenance tasks`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeManageVolumePrivilege.ps1">Download Script: Configure-UraSeManageVolumePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeManageVolumePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semanagevolumeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semanagevolumeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeManageVolumePrivilege\s*=") {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeManageVolumePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeManageVolumePrivilegeStatus.ps1">Download Script: Get-UraSeManageVolumePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeManageVolumePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_semanagevolumeprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeManageVolumePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeManageVolumePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_semanagevolumeprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_semanagevolumeprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeManageVolumePrivilege\s*=") {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeManageVolumePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeManageVolumePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8117" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-118" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-118] Configure User Rights: Profile single process</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-110](../../07-paws/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-131](../../02-domain-controllers/user-rights/configure-ura-seprofilesingleprocessprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seprofilesingleprocessprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeProfileSingleProcessPrivilege</xhtml:code> allows a process to monitor and profile the performance and execution metrics of non-system processes using Windows performance sampling APIs. Profiling tools monitor instruction execution rates, thread context switches, memory cache behavior, and execution sampling.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Profile single process`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeProfileSingleProcessPrivilege.ps1">Download Script: Configure-UraSeProfileSingleProcessPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeProfileSingleProcessPrivilegeStatus.ps1">Download Script: Get-UraSeProfileSingleProcessPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeProfileSingleProcessPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seprofilesingleprocessprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeProfileSingleProcessPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeProfileSingleProcessPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seprofilesingleprocessprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seprofilesingleprocessprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeProfileSingleProcessPrivilege\s*=") {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeProfileSingleProcessPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeProfileSingleProcessPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8118" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-119" severity="low" weight="10.0" selected="false">
        <title>[REQ-END-119] Configure User Rights: Profile system performance</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sesystemprofileprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeSystemProfilePrivilege</xhtml:code> allows a process to use performance monitoring tools to sample and profile operating system-wide and kernel-level performance via Windows tracing APIs and hardware performance counters.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Profile system performance`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators), *S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420 (WdiServiceHost)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeSystemProfilePrivilege.ps1">Download Script: Configure-UraSeSystemProfilePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeSystemProfilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemprofileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemprofileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemProfilePrivilege\s*=") {
        $NewLines += "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420")
    } else {
        $NewLines += "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeSystemProfilePrivilegeStatus.ps1">Download Script: Get-UraSeSystemProfilePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeSystemProfilePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sesystemprofileprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeSystemProfilePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeSystemProfilePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sesystemprofileprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sesystemprofileprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeSystemProfilePrivilege\s*=") {
        $NewLines += "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420")
    } else {
        $NewLines += "SeSystemProfilePrivilege = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8119" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-120" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-120] Configure User Rights: Replace a process level token</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-seassignprimarytokenprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeAssignPrimaryTokenPrivilege</xhtml:code> allows a process to assign a primary security access token to a newly initialized process via APIs such as <xhtml:code>CreateProcessAsUser</xhtml:code> or <xhtml:code>SetInformationJobObject</xhtml:code>. In the Windows NT security architecture, every process runs under a primary token that defines its user SID, group memberships, privileges, and Mandatory Integrity Control (MIC) level. Under normal conditions, child processes automatically inherit a duplicate of the parent process primary token. When a process holds <xhtml:code>SeAssignPrimaryTokenPrivilege</xhtml:code>, it can substitute an arbitrary primary token obtained from another session, service, or authentication handshake, effectively launching programs under the security context of any arbitrary user or the local SYSTEM account.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Replace a process-level token`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-19 (LocalService), *S-1-5-20 (NetworkService)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeAssignPrimaryTokenPrivilege.ps1">Download Script: Configure-UraSeAssignPrimaryTokenPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeAssignPrimaryTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seassignprimarytokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seassignprimarytokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeAssignPrimaryTokenPrivilege\s*=") {
        $NewLines += "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20")
    } else {
        $NewLines += "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeAssignPrimaryTokenPrivilegeStatus.ps1">Download Script: Get-UraSeAssignPrimaryTokenPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeAssignPrimaryTokenPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_seassignprimarytokenprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeAssignPrimaryTokenPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-19,*S-1-5-20"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeAssignPrimaryTokenPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_seassignprimarytokenprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_seassignprimarytokenprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeAssignPrimaryTokenPrivilege\s*=") {
        $NewLines += "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20")
    } else {
        $NewLines += "SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8120" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-121" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-121] Configure User Rights: Restore files and directories</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-111](../../07-paws/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-132](../../02-domain-controllers/user-rights/configure-ura-serestoreprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-serestoreprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRestorePrivilege</xhtml:code> grants the caller the capability to bypass all write-access security controls (DACLs) across the entire NTFS filesystem and Windows Registry. When a process opens a file or registry key handle specifying <xhtml:code>FILE_FLAG_BACKUP_SEMANTICS</xhtml:code> in Win32 APIs, the kernel explicitly bypasses standard security descriptor DACL checks, allowing the process to write to, overwrite, or delete any file or key on the system. In addition, this privilege grants the ability to set any valid user or group SID as the owner of an object.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Restore files and directories`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeRestorePrivilege.ps1">Download Script: Configure-UraSeRestorePrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeRestorePrivilegeStatus.ps1">Download Script: Get-UraSeRestorePrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeRestorePrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_serestoreprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRestorePrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeRestorePrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serestoreprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serestoreprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRestorePrivilege\s*=") {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRestorePrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeRestorePrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8121" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-122" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-122] Configure User Rights: Take ownership of files or other objects</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-112](../../07-paws/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-135](../../02-domain-controllers/user-rights/configure-ura-setakeownershipprivilege.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-setakeownershipprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeTakeOwnershipPrivilege</xhtml:code> allows a user to take ownership of any securable object in the operating system (files, directories, registry keys, Active Directory objects, printers, services) by writing the caller's SID into the object security descriptor owner field via <xhtml:code>SetNamedSecurityInfo</xhtml:code> or <xhtml:code>SetSecurityInfo</xhtml:code>. The Windows security model grants the owner of an object implicit <xhtml:code>WRITE_DAC</xhtml:code> authority.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Take ownership of files or other objects`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-32-544 (Administrators)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeTakeOwnershipPrivilege.ps1">Download Script: Configure-UraSeTakeOwnershipPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeTakeOwnershipPrivilegeStatus.ps1">Download Script: Get-UraSeTakeOwnershipPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeTakeOwnershipPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_setakeownershipprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeTakeOwnershipPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-32-544"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeTakeOwnershipPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_setakeownershipprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_setakeownershipprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeTakeOwnershipPrivilege\s*=") {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeTakeOwnershipPrivilege = *S-1-5-32-544")
    } else {
        $NewLines += "SeTakeOwnershipPrivilege = *S-1-5-32-544"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8122" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-123" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-123] Configure User Rights: Modify an object label</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers.</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-serelabelprivilege.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeRelabelPrivilege</xhtml:code> controls the ability to modify the Mandatory Integrity Control (MIC) label of securable objects via <xhtml:code>SetKernelObjectSecurity</xhtml:code> or <xhtml:code>SetNamedSecurityInfo</xhtml:code>. Windows Mandatory Integrity Control defines four primary integrity levels: Low, Medium, High, and System. MIC enforces 'No Write Up' rules, preventing a process running at a lower integrity level from writing to or modifying objects at a higher integrity level.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Modify an object label`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Add User or Group...</xhtml:strong> and ensure the principal list is empty (or remove all assigned accounts/groups so that no principals are configured).</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeRelabelPrivilege.ps1">Download Script: Configure-UraSeRelabelPrivilege.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeRelabelPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serelabelprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serelabelprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRelabelPrivilege\s*=") {
        $NewLines += "SeRelabelPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRelabelPrivilege = ")
    } else {
        $NewLines += "SeRelabelPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeRelabelPrivilegeStatus.ps1">Download Script: Get-UraSeRelabelPrivilegeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeRelabelPrivilegeStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_serelabelprivilege.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeRelabelPrivilege\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = ""
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeRelabelPrivilege.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_serelabelprivilege.cfg"
$DbFile = Join-Path $SecTempDir "secedit_serelabelprivilege.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeRelabelPrivilege\s*=") {
        $NewLines += "SeRelabelPrivilege = "
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeRelabelPrivilege = ")
    } else {
        $NewLines += "SeRelabelPrivilege = "
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8123" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-124" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-124] Configure User Rights: Deny access to this computer from the network</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-113](../../07-paws/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-117](../../02-domain-controllers/user-rights/configure-ura-sedenynetworklogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sedenynetworklogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyNetworkLogonRight</xhtml:code> explicitly prevents specified security principals from authenticating over network protocols (SMB, RPC, WMI, WinRM, LDAP, etc. - Logon Type 3). Network logons represent the primary highway for lateral movement and remote compromise in Active Directory environments. Enforcing an explicit deny stops network authentication regardless of share-level or NTFS-level permissions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny access to this computer from the network`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-113 (Local Account), *S-1-5-114 (Local Account and member of Administrators group)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeDenyNetworkLogonRight.ps1">Download Script: Configure-UraSeDenyNetworkLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeDenyNetworkLogonRightStatus.ps1">Download Script: Get-UraSeDenyNetworkLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeDenyNetworkLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenynetworklogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyNetworkLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-113,*S-1-5-114"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeDenyNetworkLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenynetworklogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenynetworklogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyNetworkLogonRight\s*=") {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyNetworkLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8124" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-125" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-125] Configure User Rights: Deny log on through Remote Desktop Services</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-114](../../07-paws/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
              <xhtml:em>(For Domain Controllers, refer to [REQ-DC-121](../../02-domain-controllers/user-rights/configure-ura-sedenyremoteinteractivelogonright.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (1809 and above), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-rights/configure-ura-sedenyremoteinteractivelogonright.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The <xhtml:code>SeDenyRemoteInteractiveLogonRight</xhtml:code> explicitly denies designated accounts the ability to establish Remote Desktop Protocol (RDP) sessions (Logon Type 10) on the target system. RDP exposes a full graphical interactive session over TCP port 3389, providing an attacker with interactive desktop capabilities and loading user credentials into memory.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to the targeted GPO linked to Tier 2 systems (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>In the console tree, browse to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment</xhtml:code>
            </xhtml:li>
            <xhtml:li>Open the policy <xhtml:strong>`Deny log on through Remote Desktop Services`</xhtml:strong>.</xhtml:li>
            <xhtml:li>Select the <xhtml:strong>Define these policy settings</xhtml:strong> check box.</xhtml:li>
            <xhtml:li>Configure the security principal allocation to: <xhtml:code>*S-1-5-113 (Local Account), *S-1-5-114 (Local Account and member of Administrators group)</xhtml:code>.</xhtml:li>
            <xhtml:li>Click <xhtml:strong>Apply</xhtml:strong> and <xhtml:strong>OK</xhtml:strong>.</xhtml:li>
            <xhtml:li>Apply and verify policy enforcement across target hosts using <xhtml:code>gpupdate /force</xhtml:code> and inspect with <xhtml:code>secedit /export /cfg C:\Windows\Temp\sec_audit.cfg</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-UraSeDenyRemoteInteractiveLogonRight.ps1">Download Script: Configure-UraSeDenyRemoteInteractiveLogonRight.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-UraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-UraSeDenyRemoteInteractiveLogonRightStatus.ps1">Download Script: Get-UraSeDenyRemoteInteractiveLogonRightStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UraSeDenyRemoteInteractiveLogonRightStatus.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_audit_sedenyremoteinteractivelogonright.cfg"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) {
    Write-Output "Non-Compliant"
    exit 1
}

$ConfigText = Get-Content -Path $CfgFile -Raw
Remove-Item -Path $CfgFile -ErrorAction SilentlyContinue

$Match = $ConfigText -match "(?mi)^\s*SeDenyRemoteInteractiveLogonRight\s*=\s*(.*)$"
$CurrentValue = ""
if ($Match) {
    $CurrentValue = $Matches[1].Trim()
}

$Expected = "*S-1-5-113,*S-1-5-114"
if ($CurrentValue -eq $Expected) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-UraSeDenyRemoteInteractiveLogonRight.ps1
$SecTempDir = Join-Path $env:TEMP "SecurityTemplates"
if (-not (Test-Path $SecTempDir)) { New-Item -Path $SecTempDir -ItemType Directory -Force | Out-Null }
$CfgFile = Join-Path $SecTempDir "ura_sedenyremoteinteractivelogonright.cfg"
$DbFile = Join-Path $SecTempDir "secedit_sedenyremoteinteractivelogonright.sdb"
$LogFile = Join-Path $SecTempDir "secedit.log"

$Process = Start-Process secedit -ArgumentList "/export /cfg `"$CfgFile`"" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -ne 0) { Throw "Failed to export security template" }

$ConfigText = Get-Content -Path $CfgFile -Raw
if ($ConfigText -notmatch "\[Privilege Rights\]") {
    $ConfigText += "`r`n[Privilege Rights]`r`n"
}

$Lines = $ConfigText -split "`r?`n"
$NewLines = @()
$InPriv = $false
$KeyAdded = $false

foreach ($Line in $Lines) {
    if ($Line -match "^\[(.*)\]$") {
        if ($Matches[1] -eq "Privilege Rights") {
            $InPriv = $true
        } else {
            $InPriv = $false
        }
    }
    if ($InPriv -and $Line -match "^\s*SeDenyRemoteInteractiveLogonRight\s*=") {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
        $KeyAdded = $true
    } else {
        $NewLines += $Line
    }
}

if (-not $KeyAdded) {
    # Find Privilege Rights section index and insert it right after
    $Idx = $NewLines.IndexOf("[Privilege Rights]")
    if ($Idx -ge 0) {
        $NewLines.Insert($Idx + 1, "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114")
    } else {
        $NewLines += "SeDenyRemoteInteractiveLogonRight = *S-1-5-113,*S-1-5-114"
    }
}

$NewLines | Set-Content -Path $CfgFile -Force
$Proc = Start-Process secedit -ArgumentList "/configure /db `"$DbFile`" /cfg `"$CfgFile`" /areas USER_RIGHTS /log `"$LogFile`"" -Wait -NoNewWindow -PassThru
if ($Proc.ExitCode -ne 0) { Throw "Failed to configure secedit user rights" }
Remove-Item -Path $CfgFile, $DbFile -ErrorAction SilentlyContinue</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8125" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_User_Profile_Restrictions">
      <title>User Profile Restrictions</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-126" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-126] User Profile: Toast Notifications Lock Screen Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-115](../../07-paws/user-profile/configure-up-toast-notifications.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-toast-notifications.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Modern desktop applications, productivity suites (Microsoft Teams, Outlook), communication channels, and identity tools routinely utilize Windows Push Notifications to display pop-up "toast" notification banners on the screen. By default, Windows allows applications to surface these notification banners "above the lock screen," presenting a major physical data leakage and credential compromise vulnerability.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Start Menu and Taskbar \ Notifications</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Turn off toast notifications on the lock screen</xhtml:strong> and set it to <xhtml:strong>Enabled</xhtml:strong>.</xhtml:li>
            <xhtml:li>
              <xhtml:em>(Optional Defense-in-Depth)</xhtml:em> Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ System \ Logon</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Set </xhtml:em>
              <xhtml:em>Turn off app notifications on the lock screen</xhtml:em>
              <xhtml:em> to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable toast notifications on the lock screen:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Uptoastnotifications.ps1">Download Script: Configure-Uptoastnotifications.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Uptoastnotifications.ps1
Write-Host "Applying User Profile restriction: toast-notifications..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoToastApplicationNotificationOnLockScreen" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UptoastnotificationsStatus.ps1">Download Script: Get-UptoastnotificationsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UptoastnotificationsStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Uptoastnotifications.ps1
Write-Host "Applying User Profile restriction: toast-notifications..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" "NoToastApplicationNotificationOnLockScreen" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoToastApplicationNotificationOnLockScreen" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8126" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-127" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-127] User Profile: Spotlight and Consumer Features Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-116](../../07-paws/user-profile/configure-up-spotlight-consumer.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-spotlight-consumer.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows consumer experiences and Windows Spotlight are cloud-integrated features designed to deliver targeted application suggestions, promotional tiles, interactive lock screen imagery, and tips to consumer endpoints. In an enterprise Active Directory domain, these features introduce significant threat surfaces, outbound network connections, and unapproved software provisioning.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Cloud Content</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Microsoft consumer experiences</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Cloud Content</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Do not show third-party suggestions in Windows spotlight</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Configure Windows spotlight on lock screen</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows spotlight on desktop</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Spotlight and Consumer Features restrictions:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upspotlightconsumer.ps1">Download Script: Configure-Upspotlightconsumer.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upspotlightconsumer.ps1
Write-Host "Applying User Profile restriction: spotlight-consumer..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableThirdPartySuggestions" -Value "1" -Type DWord -Force
    Set-ItemProperty -Path $DefaultKey -Name "ConfigureWindowsSpotlight" -Value "2" -Type DWord -Force
    Set-ItemProperty -Path $DefaultKey -Name "DisableSpotlightCollectionOnDesktop" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpspotlightconsumerStatus.ps1">Download Script: Get-UpspotlightconsumerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpspotlightconsumerStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1"
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2"
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upspotlightconsumer.ps1
Write-Host "Applying User Profile restriction: spotlight-consumer..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableThirdPartySuggestions" "1" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "ConfigureWindowsSpotlight" "2" "DWord"
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\CloudContent" "DisableSpotlightCollectionOnDesktop" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\CloudContent" "DisableWindowsConsumerFeatures" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\CloudContent"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "DisableThirdPartySuggestions" -Value "1" -Type DWord -Force
    Set-ItemProperty -Path $DefaultKey -Name "ConfigureWindowsSpotlight" -Value "2" -Type DWord -Force
    Set-ItemProperty -Path $DefaultKey -Name "DisableSpotlightCollectionOnDesktop" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8127" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-128" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-128] User Profile: Windows Copilot Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-117](../../07-paws/user-profile/configure-up-windows-copilot.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 11 Enterprise/Pro (all supported builds), Windows 10 Enterprise (where Copilot components are backported).</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-windows-copilot.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows Copilot is an artificial intelligence assistant deeply integrated into the Windows 11 desktop shell, Edge browser runtime, and search experience. Copilot utilizes cloud-hosted large language models (LLMs) to synthesize user requests, summarize screen contents, and assist with desktop workflows. In an enterprise environment, unconstrained deployment of generative AI interfaces introduces critical data loss prevention (DLP), regulatory compliance, and credential exposure hazards.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Windows Copilot</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows Copilot</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Copilot</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off Windows Copilot</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Windows Copilot:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upwindowscopilot.ps1">Download Script: Configure-Upwindowscopilot.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upwindowscopilot.ps1
Write-Host "Applying User Profile restriction: windows-copilot..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "TurnOffWindowsCopilot" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpwindowscopilotStatus.ps1">Download Script: Get-UpwindowscopilotStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpwindowscopilotStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upwindowscopilot.ps1
Write-Host "Applying User Profile restriction: windows-copilot..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" "TurnOffWindowsCopilot" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "TurnOffWindowsCopilot" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8128" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-129" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-129] User Profile: In-Place Sharing Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-118](../../07-paws/user-profile/configure-up-inplace-sharing.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-inplace-sharing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>In modern versions of Windows, File Explorer incorporates the "In-Place Sharing" framework (also known as the Share Flyout or Share Charm). This mechanism provides users with a persistent "Share" button on the Explorer ribbon and context menu, allowing files to be directly broadcasted or transmitted to third-party applications, personal email accounts, social media platforms, or nearby devices via Nearby Sharing (Bluetooth and Wi-Fi Direct).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off in-place sharing</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off in-place sharing</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable in-place sharing:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upinplacesharing.ps1">Download Script: Configure-Upinplacesharing.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upinplacesharing.ps1
Write-Host "Applying User Profile restriction: inplace-sharing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoInplaceSharing" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpinplacesharingStatus.ps1">Download Script: Get-UpinplacesharingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpinplacesharingStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upinplacesharing.ps1
Write-Host "Applying User Profile restriction: inplace-sharing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKCU:" "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "NoInplaceSharing" "1" "DWord"

# Apply to Default User profile for new sessions
$DefaultHivePath = "C:\Users\Default\NTUSER.DAT"
if (Test-Path $DefaultHivePath) {
    reg load HKU\DefaultUser $DefaultHivePath | Out-Null
    $DefaultKey = "Registry::HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
    if (-not (Test-Path $DefaultKey)) { New-Item -Path $DefaultKey -Force | Out-Null }
    Set-ItemProperty -Path $DefaultKey -Name "NoInplaceSharing" -Value "1" -Type DWord -Force
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
    reg unload HKU\DefaultUser | Out-Null
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8129" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-130" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-130] User Profile: Shell RunAs User Suppression</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-119](../../07-paws/user-profile/configure-up-runas-suppression.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-runas-suppression.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>In default Windows configurations, holding the Shift key while right-clicking an executable (<xhtml:code>.exe</xhtml:code>), command file (<xhtml:code>.cmd</xhtml:code>), batch script (<xhtml:code>.bat</xhtml:code>), or Microsoft Management Console file (<xhtml:code>.msc</xhtml:code>) exposes the "Run as different user" shell context menu command verb (<xhtml:code>runasuser</xhtml:code>). This feature encourages an anti-pattern that directly violates enterprise credential hygiene and exposes high-privilege credentials to theft on standard workstations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create four Registry Items with the following parameters:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SuppressionPolicy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>4096</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Paths</xhtml:em>*:</xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\batfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\cmdfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\exefile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>* <xhtml:code>SOFTWARE\Classes\mscfile\shell\runasuser</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Shell RunAs User suppression:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Uprunassuppression.ps1">Download Script: Configure-Uprunassuppression.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Uprunassuppression.ps1
Write-Host "Applying User Profile restriction: runas-suppression..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UprunassuppressionStatus.ps1">Download Script: Get-UprunassuppressionStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UprunassuppressionStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096"
Test-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Uprunassuppression.ps1
Write-Host "Applying User Profile restriction: runas-suppression..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Classes\batfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\cmdfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\exefile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Classes\mscfile\shell\runasuser" "SuppressionPolicy" "4096" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8130" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-131" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-131] User Profile: Personalization and Privacy Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-120](../../07-paws/user-profile/configure-up-personalization-privacy.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-personalization-privacy.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows personalization and input learning features enhance the consumer user experience by providing voice activation, dynamic lock screen slideshows, camera access, and predictive typing. In an enterprise security environment, these unauthenticated and telemetry-driven features introduce physical reconnaissance vulnerabilities, memory corruption attack surfaces, and persistent keystroke data collection.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Control Panel \ Personalization</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Prevent enabling lock screen camera</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Prevent enabling lock screen slide show</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ App Privacy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Let Windows apps activate with voice above lock</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>In the drop-down menu, select: <xhtml:strong>Force Deny</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Control Panel \ Regional and Language Options \ Handwriting personalization</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Turn off automatic learning</xhtml:strong>: Set to <xhtml:strong>Enabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Personalization and Privacy restrictions:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Uppersonalizationprivacy.ps1">Download Script: Configure-Uppersonalizationprivacy.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Uppersonalizationprivacy.ps1
Write-Host "Applying User Profile restriction: personalization-privacy..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UppersonalizationprivacyStatus.ps1">Download Script: Get-UppersonalizationprivacyStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UppersonalizationprivacyStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Uppersonalizationprivacy.ps1
Write-Host "Applying User Profile restriction: personalization-privacy..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenCamera" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Personalization" "NoLockScreenSlideshow" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" "LetAppsActivateWithVoiceAboveLock" "2" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\InputPersonalization" "AllowInputPersonalization" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8131" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-132" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-132] User Profile: Group Policy Registry Policy Processing Behaviors</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to reciprocal baseline [REQ-PAW-121](../../07-paws/user-profile/configure-up-gp-processing.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-gp-processing.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Group Policy processing in Windows relies on Client-Side Extensions (CSEs). Each CSE is registered under <xhtml:code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions</xhtml:code> with a unique GUID. The GUID <xhtml:code>{35378EAC-683F-11D2-A89A-00C04FBBCFA2}</xhtml:code> represents the primary <xhtml:strong>Registry Client-Side Extension</xhtml:strong> (<xhtml:code>gptext.dll</xhtml:code>), which is responsible for applying Administrative Templates (<xhtml:code>.admx</xhtml:code>/<xhtml:code>.adml</xhtml:code> policies) and direct registry modifications defined across applied Group Policy Objects.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ System \ Group Policy</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Configure Registry policy processing</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Process even if the Group Policy objects have not changed</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Ensure </xhtml:em>
              <xhtml:em>Do not apply during periodic background processing</xhtml:em>
              <xhtml:em> is </xhtml:em>
              <xhtml:em>unchecked</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy propagation using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the Registry CSE processing behaviors:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upgpprocessing.ps1">Download Script: Configure-Upgpprocessing.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upgpprocessing.ps1
Write-Host "Applying User Profile restriction: gp-processing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpgpprocessingStatus.ps1">Download Script: Get-UpgpprocessingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpgpprocessingStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upgpprocessing.ps1
Write-Host "Applying User Profile restriction: gp-processing..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoBackgroundPolicy" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" "NoGPOListChanges" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8132" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-133" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-133] User Profile: Telemetry and Inventory Collection Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to reciprocal baseline [REQ-PAW-122](../../07-paws/user-profile/configure-up-telemetry-inventory.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-telemetry-inventory.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Modern Windows operating systems include background diagnostic, telemetry, and inventory scanning subsystems designed to evaluate system health, application compatibility, and user experience telemetry. These subsystems are driven primarily by the <xhtml:strong>Connected User Experiences and Telemetry</xhtml:strong> service (<xhtml:code>DiagTrack</xhtml:code>) and the <xhtml:strong>Microsoft Compatibility Appraiser</xhtml:strong> scheduled task (<xhtml:code>CompatTelRunner.exe</xhtml:code>).</xhtml:p>
          <xhtml:p>While helpful in consumer environments, uncontrolled inventory collection and extensive diagnostic data uploads introduce distinct operational and security risks in hardened enterprise deployments.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Application Compatibility</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Turn off Inventory Collector</xhtml:em>
              <xhtml:em> -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Data Collection and Preview Builds</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Allow Diagnostic Data</xhtml:em>
              <xhtml:em> (or </xhtml:em>
              <xhtml:em>Allow Telemetry</xhtml:em>
              <xhtml:em>) -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em>, and choose </xhtml:em>
              <xhtml:em>Send required diagnostic data</xhtml:em>
              <xhtml:em> (or </xhtml:em>
              <xhtml:em>1 - Basic</xhtml:em>*).</xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Limit Enhanced diagnostic data to the minimum required by Windows Analytics</xhtml:em>
              <xhtml:em> -&gt; Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the target Organizational Unit and enforce policy application with <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce inventory and telemetry restrictions:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Uptelemetryinventory.ps1">Download Script: Configure-Uptelemetryinventory.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Uptelemetryinventory.ps1
Write-Host "Applying User Profile restriction: telemetry-inventory..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UptelemetryinventoryStatus.ps1">Download Script: Get-UptelemetryinventoryStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UptelemetryinventoryStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Uptelemetryinventory.ps1
Write-Host "Applying User Profile restriction: telemetry-inventory..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\AppCompat" "DisableInventory" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "AllowTelemetry" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\DataCollection" "LimitEnhancedDiagnosticDataWindowsAnalytics" "1" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8133" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-134" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-134] User Profile: Explorer Security and Memory Protections</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-123](../../07-paws/user-profile/configure-up-explorer-security.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-explorer-security.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows File Explorer (<xhtml:code>explorer.exe</xhtml:code>) is the primary interactive user shell and file management environment in Windows. Because Explorer regularly parses untrusted file metadata, extracts icon caches, hosts third-party shell preview handlers, and processes custom URL protocol schemes, it represents a prime target for memory corruption exploits and arbitrary command execution.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ File Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Turn off Data Execution Prevention for Explorer</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Turn off heap termination on corruption</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Shell Protocol Protected Mode</xhtml:em>
              <xhtml:em>: Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Explorer security and memory protections:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upexplorersecurity.ps1">Download Script: Configure-Upexplorersecurity.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upexplorersecurity.ps1
Write-Host "Applying User Profile restriction: explorer-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpexplorersecurityStatus.ps1">Download Script: Get-UpexplorersecurityStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpexplorersecurityStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upexplorersecurity.ps1
Write-Host "Applying User Profile restriction: explorer-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoDataExecutionPrevention" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Explorer" "NoHeapTerminationOnCorruption" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" "PreXPSP2ShellProtocolBehavior" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8134" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-135" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-135] User Profile: Internet Explorer Options and Feeds Restrictions</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to reciprocal baseline [REQ-PAW-124](../../07-paws/user-profile/configure-up-ie-security.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-ie-security.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Although modern versions of Windows 10 and Windows 11 have retired the standalone Internet Explorer 11 browser in favor of Microsoft Edge (Chromium), core legacy components of the Trident engine (<xhtml:code>mshtml.dll</xhtml:code>), the Windows Internet API (<xhtml:code>wininet.dll</xhtml:code>), URLMon, and the <xhtml:strong>Windows RSS Platform</xhtml:strong> (<xhtml:code>msfeeds.dll</xhtml:code>, <xhtml:code>msfeedssync.exe</xhtml:code>) remain deeply embedded in the operating system. These legacy subsystems are maintained for backward compatibility with legacy COM automation, WebBrowser controls, and internal enterprise tools.</xhtml:p>
          <xhtml:p>Because these legacy components remain active in the background, they represent a persistent attack surface if left unconfigured.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Internet Explorer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Disable Internet Explorer 11 as a standalone browser</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em>, and select </xhtml:em>
              <xhtml:em>Always</xhtml:em>*.</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ RSS Feeds</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Prevent downloading of enclosures</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>
              <xhtml:em> Double-click </xhtml:em>
              <xhtml:em>Turn on Basic feed authentication over HTTP</xhtml:em>
              <xhtml:em> -&gt; Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>*.</xhtml:li>
            <xhtml:li>Link the GPO to the target Organizational Unit and enforce policy application with <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Internet Explorer and RSS feed security restrictions:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upiesecurity.ps1">Download Script: Configure-Upiesecurity.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upiesecurity.ps1
Write-Host "Applying User Profile restriction: ie-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpiesecurityStatus.ps1">Download Script: Get-UpiesecurityStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpiesecurityStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upiesecurity.ps1
Write-Host "Applying User Profile restriction: ie-security..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Main" "NotifyDisableIEOptions" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "DisableEnclosureDownload" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" "AllowBasicAuthInClear" "0" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8135" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-136" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-136] User Profile: Interactive Logon Warning Banners</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-125](../../07-paws/user-profile/configure-up-logon-banners.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-logon-banners.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Interactive logon configurations govern the initial security boundary when an operator or user accesses the Windows console. Two critical security parameters are enforced: disabling Automatic Restart Sign-On (ARSO) to protect credentials in memory across reboots, and enforcing legally binding pre-logon warning banners to establish authorization boundaries and consent to monitoring.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Interactive logon: Message text for users attempting to log on</xhtml:strong>: Enter organizational warning text (e.g., <xhtml:code>You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring.</xhtml:code>)</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Interactive logon: Message title for users attempting to log on</xhtml:strong>: Enter warning title (e.g., <xhtml:code>US Department of Defense Warning Statement</xhtml:code>)</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Logon Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Sign-in and lock last interactive user automatically after a restart or cold boot</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure Interactive Logon warning banners and disable ARSO:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Uplogonbanners.ps1">Download Script: Configure-Uplogonbanners.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Uplogonbanners.ps1
Write-Host "Applying User Profile restriction: logon-banners..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring." "String"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement" "String"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UplogonbannersStatus.ps1">Download Script: Get-UplogonbannersStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UplogonbannersStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring."
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Uplogonbanners.ps1
Write-Host "Applying User Profile restriction: logon-banners..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "DisableAutomaticRestartSignOn" "1" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeText" "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS, you consent to routine monitoring." "String"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "LegalNoticeCaption" "US Department of Defense Warning Statement" "String"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8136" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-137" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-137] User Profile: Interactive Logon Inactivity Timeout</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-126](../../07-paws/user-profile/configure-up-inactivity-timeout.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-inactivity-timeout.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>In enterprise environments, authorized employees and operators frequently leave workstations unattended—to attend meetings, take breaks, or collaborate elsewhere in the facility. If a workstation remains unlocked while unattended, any individual with physical access to the machine can interact with the active user's session, execute unauthorized commands, exfiltrate sensitive files, or install persistence mechanisms without needing to authenticate.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Interactive logon: Machine inactivity limit</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Define this policy setting</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Set </xhtml:em>
              <xhtml:em>The machine will be locked after</xhtml:em>*: <xhtml:code>900</xhtml:code> seconds</xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce the machine inactivity timeout limit:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upinactivitytimeout.ps1">Download Script: Configure-Upinactivitytimeout.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upinactivitytimeout.ps1
Write-Host "Applying User Profile restriction: inactivity-timeout..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpinactivitytimeoutStatus.ps1">Download Script: Get-UpinactivitytimeoutStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpinactivitytimeoutStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upinactivitytimeout.ps1
Write-Host "Applying User Profile restriction: inactivity-timeout..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "InactivityTimeoutSecs" "900" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8137" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-138" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-138] User Profile: Windows Installer Hardening</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-127](../../07-paws/user-profile/configure-up-installer-hardening.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-installer-hardening.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows Installer (<xhtml:code>msiexec.exe</xhtml:code>) executes as a privileged Windows service (<xhtml:code>NT AUTHORITY\SYSTEM</xhtml:code>) to manage the installation, repair, and removal of software packages across the operating system. Misconfigurations in Windows Installer policies introduce some of the most critical, well-known Local Privilege Escalation (LPE) vulnerabilities in the Windows operating system.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Configure the following policies:</xhtml:li>
          </xhtml:ol>
          <xhtml:ul>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Installer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Always install with elevated privileges</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Allow user control over installs</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Windows Installer</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Always install with elevated privileges</xhtml:strong>: Set to <xhtml:strong>Disabled</xhtml:strong>
            </xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Add Registry Item: <xhtml:code>HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer\DisableCoInstallers</xhtml:code> = <xhtml:code>1</xhtml:code> (DWord)</xhtml:li>
          </xhtml:ul>
          <xhtml:ol>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the Windows Installer hardening settings:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upinstallerhardening.ps1">Download Script: Configure-Upinstallerhardening.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upinstallerhardening.ps1
Write-Host "Applying User Profile restriction: installer-hardening..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpinstallerhardeningStatus.ps1">Download Script: Get-UpinstallerhardeningStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpinstallerhardeningStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0"
Test-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0"
Test-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upinstallerhardening.ps1
Write-Host "Applying User Profile restriction: installer-hardening..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "EnableUserControl" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "AlwaysInstallElevated" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Policies\Microsoft\Windows\Installer" "SafeForScripting" "0" "DWord"
Set-RegValue "HKLM:" "SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer" "DisableCoInstallers" "1" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8138" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-139" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-139] User Profile: Secondary Logon Service Lockdown</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-128](../../07-paws/user-profile/configure-up-seclogon-service.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-up-seclogon-service.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Secondary Logon service (<xhtml:code>seclogon.dll</xhtml:code>, executed within <xhtml:code>svchost.exe</xhtml:code>) provides the runtime infrastructure that enables the <xhtml:code>CreateProcessWithLogonW</xhtml:code> and <xhtml:code>CreateProcessWithTokenW</xhtml:code> Win32 APIs, powering the native Windows <xhtml:code>runas.exe</xhtml:code> utility and interactive "Run as different user" GUI options. While designed to facilitate administrative convenience, the Secondary Logon service introduces severe local privilege escalation risks and undermines enterprise credential tiering hygiene.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Windows Settings \ Security Settings \ System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Secondary Logon</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Check </xhtml:em>
              <xhtml:em>Define this policy setting</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable the Secondary Logon service:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Upseclogonservice.ps1">Download Script: Configure-Upseclogonservice.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Upseclogonservice.ps1
Write-Host "Applying User Profile restriction: seclogon-service..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4" "DWord"
</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-UpseclogonserviceStatus.ps1">Download Script: Get-UpseclogonserviceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-UpseclogonserviceStatus.ps1
$script:Vulnerable = $false

function Test-RegValue {
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$expected
    )
    $fullPath = "$hive\$keyPath"
    $val = Get-ItemProperty -Path $fullPath -Name $name -ErrorAction SilentlyContinue
    $actual = if ($val) { $val.$name } else { "" }
    if ($actual -ne $expected) {
        $script:Vulnerable = $true
    }
}
Test-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4"

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Upseclogonservice.ps1
Write-Host "Applying User Profile restriction: seclogon-service..." -ForegroundColor Cyan

function Set-RegValue {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$hive,
        [string]$keyPath,
        [string]$name,
        [string]$value,
        [string]$type
    )
    if ($PSCmdlet.ShouldProcess("$hive\$keyPath", "Set registry value $name to $value")) {
        $fullPath = "$hive\$keyPath"
        $parent = Split-Path -Path $fullPath
        if (-not (Test-Path $parent)) { New-Item -Path $parent -Force | Out-Null }
        if (-not (Test-Path $fullPath)) { New-Item -Path $fullPath -Force | Out-Null }
        Set-ItemProperty -Path $fullPath -Name $name -Value $value -Type $type -Force
    }
}
Set-RegValue "HKLM:" "SYSTEM\CurrentControlSet\Services\seclogon" "Start" "4" "DWord"</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8139" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-151" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-151] User Profile: Structured Exception Handling Overwrite Protection (SEHOP) for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-140](../../07-paws/user-profile/configure-paw-up-sehop.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-sehop.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Structured Exception Handling (SEH) is a core Win32 application mechanism designed to manage runtime hardware and software exceptions. However, 32-bit Win32 and WOW64 processes maintain SEH records directly on the thread's stack, creating a classic attack vector for stack buffer overflows where adversaries hijack exception dispatching to execute arbitrary shellcode.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\kernel</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>DisableExceptionChainValidation</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>DisableExceptionChainValidation</xhtml:code> requires a system restart to take effect on the kernel exception dispatcher.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce SEHOP exception chain validation:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditSehop.ps1">Download Script: Configure-EndAuditSehop.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditSehop.ps1
Write-Host "Enforcing System Mitigation control: sehop..." -ForegroundColor Cyan

# Set Registry value: DisableExceptionChainValidation
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "    Enforced DisableExceptionChainValidation = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditSehopStatus.ps1">Download Script: Get-EndAuditSehopStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditSehopStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: DisableExceptionChainValidation
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.DisableExceptionChainValidation -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditSehop.ps1
Write-Host "Enforcing System Mitigation control: sehop..." -ForegroundColor Cyan

# Set Registry value: DisableExceptionChainValidation
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "    Enforced DisableExceptionChainValidation = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8151" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-152" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-152] User Profile: Directory Protection Mode for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-141](../../07-paws/user-profile/configure-paw-up-protection-mode.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-protection-mode.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Securing the Windows system root and core system directories against unauthorized modification is essential to preventing Local Privilege Escalation (LPE) and DLL planting attacks. The <xhtml:code>ProtectionMode</xhtml:code> registry setting configures the Windows Session Manager (<xhtml:code>smss.exe</xhtml:code>) to enforce hardened security descriptors across critical system directories and Object Manager namespaces during operating system initialization.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>ProtectionMode</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>ProtectionMode</xhtml:code> requires a computer restart to apply to the Session Manager during initial boot.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Directory Protection Mode:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditProtectionmode.ps1">Download Script: Configure-EndAuditProtectionmode.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditProtectionmode.ps1
Write-Host "Enforcing System Mitigation control: protection-mode..." -ForegroundColor Cyan

# Set Registry value: ProtectionMode
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -Value 1 -Type DWord -Force
Write-Host "    Enforced ProtectionMode = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditProtectionmodeStatus.ps1">Download Script: Get-EndAuditProtectionmodeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditProtectionmodeStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: ProtectionMode
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.ProtectionMode -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditProtectionmode.ps1
Write-Host "Enforcing System Mitigation control: protection-mode..." -ForegroundColor Cyan

# Set Registry value: ProtectionMode
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -Value 1 -Type DWord -Force
Write-Host "    Enforced ProtectionMode = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8152" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-153" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-153] User Profile: Address Space Layout Randomization (ASLR) Image Relocation for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-142](../../07-paws/user-profile/configure-paw-up-aslr-relocation.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-aslr-relocation.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Address Space Layout Randomization (ASLR) is a foundational defense against memory corruption vulnerabilities. By randomizing the memory locations of program headers, code segments, stacks, heaps, and libraries, ASLR ensures that an adversary cannot reliably predict target memory addresses when attempting to hijack execution flow.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>MoveImages</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>4294967295</xhtml:code> (Decimal) or <xhtml:code>0xFFFFFFFF</xhtml:code> (Hexadecimal)</xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: Enforcing <xhtml:code>MoveImages</xhtml:code> requires a computer restart to apply to core operating system kernel processes.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce system-wide ASLR image relocation:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAslrrelocation.ps1">Download Script: Configure-EndAuditAslrrelocation.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAslrrelocation.ps1
Write-Host "Enforcing System Mitigation control: aslr-relocation..." -ForegroundColor Cyan

# Set Registry value: MoveImages
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -Value 4294967295 -Type DWord -Force
Write-Host "    Enforced MoveImages = 4294967295" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditAslrrelocationStatus.ps1">Download Script: Get-EndAuditAslrrelocationStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAslrrelocationStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: MoveImages
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.MoveImages -ne 4294967295) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAslrrelocation.ps1
Write-Host "Enforcing System Mitigation control: aslr-relocation..." -ForegroundColor Cyan

# Set Registry value: MoveImages
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "MoveImages" -Value 4294967295 -Type DWord -Force
Write-Host "    Enforced MoveImages = 4294967295" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8153" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-154" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-154] User Profile: Speculative Execution Mitigations (Spectre/Meltdown) for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-143](../../07-paws/user-profile/configure-paw-up-speculative-mitigations.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-speculative-mitigations.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Transient execution vulnerabilities (such as Spectre, Meltdown, Foreshadow/L1TF, and Microarchitectural Data Sampling / MDS) break architectural isolation boundaries by exploiting CPU speculative execution and out-of-order execution optimizations. Hardware cache side-channel attacks allow unprivileged user-mode processes to reconstruct secret memory contents from kernel address space and adjacent processes.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>FeatureSettingsOverride</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>72</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a second Registry Item:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>FeatureSettingsOverrideMask</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>3</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
            <xhtml:li>Note: A computer restart is required for the Windows kernel to initialize speculative CPU execution mitigations.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce speculative execution mitigations:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditSpeculativemitigations.ps1">Download Script: Configure-EndAuditSpeculativemitigations.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditSpeculativemitigations.ps1
Write-Host "Enforcing System Mitigation control: speculative-mitigations..." -ForegroundColor Cyan

# Set Registry value: FeatureSettingsOverride
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -Value 72 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverride = 72" -ForegroundColor Green

# Set Registry value: FeatureSettingsOverrideMask
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -Value 3 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverrideMask = 3" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditSpeculativemitigationsStatus.ps1">Download Script: Get-EndAuditSpeculativemitigationsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditSpeculativemitigationsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: FeatureSettingsOverride
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.FeatureSettingsOverride -ne 72) {
    $script:Vulnerable = $true
}

# Audit Registry value: FeatureSettingsOverrideMask
$RegVal = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.FeatureSettingsOverrideMask -ne 3) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditSpeculativemitigations.ps1
Write-Host "Enforcing System Mitigation control: speculative-mitigations..." -ForegroundColor Cyan

# Set Registry value: FeatureSettingsOverride
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverride" -Value 72 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverride = 72" -ForegroundColor Green

# Set Registry value: FeatureSettingsOverrideMask
if (-not (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "FeatureSettingsOverrideMask" -Value 3 -Type DWord -Force
Write-Host "    Enforced FeatureSettingsOverrideMask = 3" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8154" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-155" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-155] User Profile: Authenticode Signature Certificate Padding Check for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-144](../../07-paws/user-profile/configure-paw-up-cert-padding.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-cert-padding.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Digital signature verification (Authenticode) is the foundational trust boundary used by Windows Defender Application Control (WDAC), AppLocker, Antivirus engines, and the operating system loader to establish software provenance and integrity. A fundamental design loophole in legacy Authenticode validation allows adversaries to tamper with signed binaries without invalidating their digital signature unless strict certificate padding validation is enforced.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> (Native 64-bit) and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>Software\Microsoft\Cryptography\Wintrust\Config</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>EnableCertPaddingCheck</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> (WOW64 32-bit) and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>EnableCertPaddingCheck</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Authenticode certificate padding validation:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditCertpadding.ps1">Download Script: Configure-EndAuditCertpadding.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditCertpadding.ps1
Write-Host "Enforcing System Mitigation control: cert-padding..." -ForegroundColor Cyan

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditCertpaddingStatus.ps1">Download Script: Get-EndAuditCertpaddingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditCertpaddingStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: EnableCertPaddingCheck
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.EnableCertPaddingCheck -ne 1) {
    $script:Vulnerable = $true
}

# Audit Registry value: EnableCertPaddingCheck
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.EnableCertPaddingCheck -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditCertpadding.ps1
Write-Host "Enforcing System Mitigation control: cert-padding..." -ForegroundColor Cyan

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green

# Set Registry value: EnableCertPaddingCheck
if (-not (Test-Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config")) { New-Item -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
Write-Host "    Enforced EnableCertPaddingCheck = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8155" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-156" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-156] User Profile: Command Processor Batch File Locking for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-145](../../07-paws/user-profile/configure-paw-up-lock-batch-files.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-lock-batch-files.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Command Processor (<xhtml:code>cmd.exe</xhtml:code>) is widely utilized for system administration, software installation routines, and scheduled maintenance tasks. By default, <xhtml:code>cmd.exe</xhtml:code> executes batch files (<xhtml:code>.bat</xhtml:code> and <xhtml:code>.cmd</xhtml:code>) using a streaming file read approach rather than caching the entire script in memory or acquiring a persistent file lock. This design exposes systems to Time-of-Check to Time-of-Use (TOCTOU) race conditions and dynamic script manipulation attacks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Command Processor</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LockBatchFilesWhenInUse</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Command Processor batch file locking:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditLockbatchfiles.ps1">Download Script: Configure-EndAuditLockbatchfiles.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditLockbatchfiles.ps1
Write-Host "Enforcing System Mitigation control: lock-batch-files..." -ForegroundColor Cyan

# Set Registry value: LockBatchFilesWhenInUse
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Command Processor")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -Value 1 -Type DWord -Force
Write-Host "    Enforced LockBatchFilesWhenInUse = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditLockbatchfilesStatus.ps1">Download Script: Get-EndAuditLockbatchfilesStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditLockbatchfilesStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: LockBatchFilesWhenInUse
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LockBatchFilesWhenInUse -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditLockbatchfiles.ps1
Write-Host "Enforcing System Mitigation control: lock-batch-files..." -ForegroundColor Cyan

# Set Registry value: LockBatchFilesWhenInUse
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Command Processor")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Command Processor" -Name "LockBatchFilesWhenInUse" -Value 1 -Type DWord -Force
Write-Host "    Enforced LockBatchFilesWhenInUse = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8156" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-157" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-157] User Profile: Time-Travel Debugging (TTD) Recording Policy for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-146](../../07-paws/user-profile/configure-paw-up-ttd-recording.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-ttd-recording.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Time-Travel Debugging (TTD) is an advanced diagnostic framework embedded in Microsoft development and troubleshooting tooling (such as WinDbg Preview and Windows Diagnostic Infrastructure). TTD works by recording a complete, instruction-by-instruction execution history of a process into a high-fidelity trace file (<xhtml:code>.run</xhtml:code>), which can then be replayed forwards and backwards in time. In an enterprise environment, unconstrained TTD recording represents a severe data exfiltration and credential theft vulnerability.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\TTD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>RecordingPolicy</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Time-Travel Debugging recording:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditTtdrecording.ps1">Download Script: Configure-EndAuditTtdrecording.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditTtdrecording.ps1
Write-Host "Enforcing System Mitigation control: ttd-recording..." -ForegroundColor Cyan

# Set Registry value: RecordingPolicy
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\TTD")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -Value 2 -Type DWord -Force
Write-Host "    Enforced RecordingPolicy = 2" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditTtdrecordingStatus.ps1">Download Script: Get-EndAuditTtdrecordingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditTtdrecordingStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: RecordingPolicy
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.RecordingPolicy -ne 2) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditTtdrecording.ps1
Write-Host "Enforcing System Mitigation control: ttd-recording..." -ForegroundColor Cyan

# Set Registry value: RecordingPolicy
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\TTD")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\TTD" -Name "RecordingPolicy" -Value 2 -Type DWord -Force
Write-Host "    Enforced RecordingPolicy = 2" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8157" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-158" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-158] User Profile: Trusted Root Store Protected Roots Certificate Restriction for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-147](../../07-paws/user-profile/configure-paw-up-protected-roots.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-protected-roots.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows CryptoAPI Trusted Root Certification Authorities store (<xhtml:code>Root</xhtml:code>) defines the ultimate trust anchors for TLS/SSL communication, Kerberos PKINIT authentication, code signing, and digital identity verification. If an adversary, malicious script, or unauthorized third-party software can inject a rogue Certificate Authority (CA) into the trusted root store, the cryptographic integrity of all network communication and software trust models is completely undermined.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>Flags</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>1</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce Protected Roots certificate restrictions:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditProtectedroots.ps1">Download Script: Configure-EndAuditProtectedroots.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditProtectedroots.ps1
Write-Host "Enforcing System Mitigation control: protected-roots..." -ForegroundColor Cyan

# Set Registry value: Flags
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -Value 1 -Type DWord -Force
Write-Host "    Enforced Flags = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditProtectedrootsStatus.ps1">Download Script: Get-EndAuditProtectedrootsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditProtectedrootsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: Flags
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.Flags -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditProtectedroots.ps1
Write-Host "Enforcing System Mitigation control: protected-roots..." -ForegroundColor Cyan

# Set Registry value: Flags
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\ProtectedRoots" -Name "Flags" -Value 1 -Type DWord -Force
Write-Host "    Enforced Flags = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8158" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-159" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-159] User Profile: Disabling Injection of AppInit DLLs for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-148](../../07-paws/user-profile/configure-paw-up-appinit-dlls.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-appinit-dlls.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>AppInit_DLLs is a legacy Windows application infrastructure mechanism dating back to Windows NT. It allows system administrators and software vendors to specify a list of dynamic-link libraries (DLLs) that are automatically loaded into the virtual address space of every user-mode process that links against <xhtml:code>User32.dll</xhtml:code>. Because nearly all interactive Win32 desktop applications, Windows system binaries, and management utilities load <xhtml:code>User32.dll</xhtml:code>, this mechanism represents a pervasive, high-risk attack surface for persistence, privilege escalation, and stealthy code injection.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>Right-click <xhtml:strong>Registry</xhtml:strong> -&gt; <xhtml:strong>New</xhtml:strong> -&gt; <xhtml:strong>Registry Item</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>LoadAppInit_DLLs</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>0</xhtml:code>
            </xhtml:li>
            <xhtml:li>Create a secondary Registry Item to clear the DLL list:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>AppInit_DLLs</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_SZ</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>""</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to configure the AppInit DLL lockdown registry settings:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAppinitdlls.ps1">Download Script: Configure-EndAuditAppinitdlls.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAppinitdlls.ps1
Write-Host "Enforcing System Mitigation control: appinit-dlls..." -ForegroundColor Cyan

# Set Registry value: LoadAppInit_DLLs
if (-not (Test-Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows")) { New-Item -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord -Force
Write-Host "    Enforced LoadAppInit_DLLs = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditAppinitdllsStatus.ps1">Download Script: Get-EndAuditAppinitdllsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAppinitdllsStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: LoadAppInit_DLLs
$RegVal = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LoadAppInit_DLLs -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAppinitdlls.ps1
Write-Host "Enforcing System Mitigation control: appinit-dlls..." -ForegroundColor Cyan

# Set Registry value: LoadAppInit_DLLs
if (-not (Test-Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows")) { New-Item -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord -Force
Write-Host "    Enforced LoadAppInit_DLLs = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8159" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-160" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-160] User Profile: Preservation of Attachment Zone Information for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-149](../../07-paws/user-profile/configure-paw-up-attachment-zone.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-attachment-zone.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Mark-of-the-Web (MOTW) is a vital Windows defensive mechanism that tags files downloaded from the Internet or untrusted external zones with contextual provenance metadata. When a file is received via a web browser, email client (e.g., Microsoft Outlook), or chat application, the Windows Attachment Manager (<xhtml:code>IAttachmentExecute</xhtml:code> API) writes an NTFS Alternate Data Stream (ADS) named <xhtml:code>Zone.Identifier</xhtml:code> to the downloaded file.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>User Configuration \ Administrative Templates \ Windows Components \ Attachment Manager</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em>(Optionally also navigate to `Computer Configuration \ Administrative Templates \ Windows Components \ Attachment Manager`)</xhtml:em>
            </xhtml:li>
            <xhtml:li>Configure the policy:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Policy</xhtml:em>
              <xhtml:em>: `Do not preserve zone information in file attachments` -&gt; Set to </xhtml:em>
              <xhtml:em>Disabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em>(Note: Setting this policy to Disabled enforces SaveZoneInformation = 2, ensuring zone information is preserved).</xhtml:em>
            </xhtml:li>
            <xhtml:li>Alternatively, configure the registry value via Group Policy Preferences:</xhtml:li>
            <xhtml:li>* Navigate to: <xhtml:code>Computer Configuration \ Preferences \ Windows Settings \ Registry</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> Right-click </xhtml:em>
              <xhtml:em>Registry</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>New</xhtml:em>
              <xhtml:em> -&gt; </xhtml:em>
              <xhtml:em>Registry Item</xhtml:em>* and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Action</xhtml:em>*: <xhtml:code>Update</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Hive</xhtml:em>*: <xhtml:code>HKEY_LOCAL_MACHINE</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Key Path</xhtml:em>*: <xhtml:code>SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Name</xhtml:em>*: <xhtml:code>SaveZoneInformation</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Type</xhtml:em>*: <xhtml:code>REG_DWORD</xhtml:code>
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> </xhtml:em>
              <xhtml:em>Value Data</xhtml:em>*: <xhtml:code>2</xhtml:code>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to enforce the preservation of attachment zone information:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAttachmentzone.ps1">Download Script: Configure-EndAuditAttachmentzone.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAttachmentzone.ps1
Write-Host "Enforcing System Mitigation control: attachment-zone..." -ForegroundColor Cyan

# Set Registry value: SaveZoneInformation
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -Value 2 -Type DWord -Force
Write-Host "    Enforced SaveZoneInformation = 2" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditAttachmentzoneStatus.ps1">Download Script: Get-EndAuditAttachmentzoneStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAttachmentzoneStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: SaveZoneInformation
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.SaveZoneInformation -ne 2) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAttachmentzone.ps1
Write-Host "Enforcing System Mitigation control: attachment-zone..." -ForegroundColor Cyan

# Set Registry value: SaveZoneInformation
if (-not (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments")) { New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" -Name "SaveZoneInformation" -Value 2 -Type DWord -Force
Write-Host "    Enforced SaveZoneInformation = 2" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8160" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-161" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-161] User Profile: Disable Windows Game DVR for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-150](../../07-paws/user-profile/configure-paw-up-game-dvr.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-game-dvr.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Windows Game Recording and Broadcasting (Game DVR) is a consumer-oriented multimedia subsystem built into Windows 10 and 11. Designed to capture gaming clips, broadcast live gameplay, and maintain background rolling video buffers, the Game DVR subsystem introduces severe information disclosure risks, unmonitored desktop recording pathways, and unnecessary system resource utilization on enterprise workstations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Game Recording and Broadcasting</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Enables or disables Windows Game Recording and Broadcasting</xhtml:strong> and set it to <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
            <xhtml:li>
              <xhtml:em>(Note: Setting this policy to Disabled enforces AllowGameDVR = 0).</xhtml:em>
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to disable Windows Game DVR:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditGamedvr.ps1">Download Script: Configure-EndAuditGamedvr.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditGamedvr.ps1
Write-Host "Enforcing System Mitigation control: game-dvr..." -ForegroundColor Cyan

# Set Registry value: AllowGameDVR
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord -Force
Write-Host "    Enforced AllowGameDVR = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditGamedvrStatus.ps1">Download Script: Get-EndAuditGamedvrStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditGamedvrStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: AllowGameDVR
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.AllowGameDVR -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditGamedvr.ps1
Write-Host "Enforcing System Mitigation control: game-dvr..." -ForegroundColor Cyan

# Set Registry value: AllowGameDVR
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord -Force
Write-Host "    Enforced AllowGameDVR = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8161" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-162" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-162] User Profile: Restrict Windows Ink Workspace on Lock Screen for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations and Member Servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-151](../../07-paws/user-profile/configure-paw-up-ink-workspace.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 Enterprise/Professional (all supported builds), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/user-profile/configure-end-up-ink-workspace.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Ink Workspace provides digital pen and stylus input capabilities, offering productivity tools such as Sticky Notes, Whiteboard, and Snip &amp; Sketch on touch-enabled devices and laptops. When unconstrained, Windows allows the Ink Workspace to be invoked while the device is locked—typically by clicking the shortcut button on an active digital stylus or tapping the lock screen icon.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit or create the target GPO linked to workstations and member servers (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to: <xhtml:code>Computer Configuration \ Administrative Templates \ Windows Components \ Windows Ink Workspace</xhtml:code>
            </xhtml:li>
            <xhtml:li>Double-click <xhtml:strong>Allow Windows Ink Workspace</xhtml:strong> and configure:</xhtml:li>
            <xhtml:li>
              <xhtml:em> Select </xhtml:em>
              <xhtml:em>Enabled</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>
              <xhtml:em> In the </xhtml:em>
              <xhtml:em>Options</xhtml:em>
              <xhtml:em> drop-down menu, select: </xhtml:em>
              <xhtml:em>On, but disallow access above lock</xhtml:em>
              <xhtml:em />
            </xhtml:li>
            <xhtml:li>Link the GPO to the appropriate Organizational Unit and verify policy enforcement using <xhtml:code>gpupdate /force</xhtml:code>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>Run the following script locally to restrict Windows Ink Workspace access above the lock screen:</xhtml:p>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditInkworkspace.ps1">Download Script: Configure-EndAuditInkworkspace.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditInkworkspace.ps1
Write-Host "Enforcing System Mitigation control: ink-workspace..." -ForegroundColor Cyan

# Set Registry value: AllowWindowsInkWorkspace
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -Value 1 -Type DWord -Force
Write-Host "    Enforced AllowWindowsInkWorkspace = 1" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndAuditInkworkspaceStatus.ps1">Download Script: Get-EndAuditInkworkspaceStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditInkworkspaceStatus.ps1
$script:Vulnerable = $false

# Audit Registry value: AllowWindowsInkWorkspace
$RegVal = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.AllowWindowsInkWorkspace -ne 1) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditInkworkspace.ps1
Write-Host "Enforcing System Mitigation control: ink-workspace..." -ForegroundColor Cyan

# Set Registry value: AllowWindowsInkWorkspace
if (-not (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -Value 1 -Type DWord -Force
Write-Host "    Enforced AllowWindowsInkWorkspace = 1" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8162" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_Services_Hardening">
      <title>Services Hardening</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-037" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-037] Disable Computer Browser Service (Browser)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-037](../../07-paws/services/disable-browser.md); for Domain Controllers, refer to [REQ-DC-016](../../02-domain-controllers/disable-smbv1.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-browser.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Computer Browser service (<xhtml:code>Browser</xhtml:code>, driven by the legacy kernel driver <xhtml:code>bowser.sys</xhtml:code>) maintains an inventory of domains, workgroups, and network servers across local network segments using unauthenticated NetBIOS over TCP/IP (NetBT) broadcast frames and Server Message Block version 1 (SMBv1) protocol datagrams.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Computer Browser</xhtml:code> (<xhtml:code>Browser</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableBrowser.ps1">Download Script: Configure-DisableBrowser.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableBrowser.ps1
# Description: Disables the unnecessary Computer Browser (Browser) service.

Write-Host "Applying hardening requirement: Disable Computer Browser service..." -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-BrowserStatus.ps1">Download Script: Get-BrowserStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-BrowserStatus.ps1
# Description: Audits the startup configuration of Computer Browser (Browser) service.

Write-Host "--- Auditing Computer Browser (Browser) Service ---" -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableBrowser.ps1
# Description: Disables the unnecessary Computer Browser (Browser) service.

Write-Host "Applying hardening requirement: Disable Computer Browser service..." -ForegroundColor Cyan

$ServiceName = "Browser"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8037" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-038" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-038] Disable Infrared Monitor Service (irmon)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-038](../../07-paws/services/disable-irmon.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-irmon.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Infrared Monitor Service (<xhtml:code>irmon</xhtml:code>, hosted within <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>irmon.dll</xhtml:code>) manages line-of-sight optical wireless communications using the legacy Infrared Data Association (IrDA) protocol stack and Object Exchange (OBEX) profiles.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Infrared monitor service</xhtml:code> (<xhtml:code>irmon</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disableirmon.ps1">Download Script: Configure-Disableirmon.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disableirmon.ps1
# Description: Disables the unnecessary Infrared monitor service (irmon) service.

Write-Host "Applying hardening requirement: Disable Infrared monitor service service..." -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-irmonStatus.ps1">Download Script: Get-irmonStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-irmonStatus.ps1
# Description: Audits the startup configuration of Infrared monitor service (irmon) service.

Write-Host "--- Auditing Infrared monitor service (irmon) Service ---" -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disableirmon.ps1
# Description: Disables the unnecessary Infrared monitor service (irmon) service.

Write-Host "Applying hardening requirement: Disable Infrared monitor service service..." -ForegroundColor Cyan

$ServiceName = "irmon"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8038" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-039" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-039] Disable Internet Connection Sharing (ICS) Service (SharedAccess)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-039](../../07-paws/services/disable-sharedaccess.md); for Domain Controllers, refer to [REQ-DC-044](../../02-domain-controllers/services/disable-sharedaccess.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-sharedaccess.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Internet Connection Sharing service (<xhtml:code>SharedAccess</xhtml:code> / ICS) provides Network Address Translation (NAT), dynamic addressing (embedded DHCP server), and name resolution (DNS proxy) capabilities to allow local devices on a network segment to share an external network connection.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Internet Connection Sharing (ICS)</xhtml:code> (<xhtml:code>SharedAccess</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSharedAccess.ps1">Download Script: Configure-DisableSharedAccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SharedAccessStatus.ps1">Download Script: Get-SharedAccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SharedAccessStatus.ps1
# Description: Audits the startup configuration of Internet Connection Sharing (ICS) (SharedAccess) service.

Write-Host "--- Auditing Internet Connection Sharing (ICS) (SharedAccess) Service ---" -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSharedAccess.ps1
# Description: Disables the unnecessary Internet Connection Sharing (ICS) (SharedAccess) service.

Write-Host "Applying hardening requirement: Disable Internet Connection Sharing (ICS) service..." -ForegroundColor Cyan

$ServiceName = "SharedAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8039" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-040" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-040] Disable LxssManager Service (LxssManager)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-040](../../07-paws/services/disable-lxssmanager.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-lxssmanager.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Subsystem for Linux (WSL) service (<xhtml:code>LxssManager</xhtml:code>) coordinates the lifecycle, initialization, and execution of Linux distributions within Windows, managing syscall translation (WSL 1) or lightweight Hyper-V micro-virtual machines (WSL 2).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>LxssManager</xhtml:code> (<xhtml:code>LxssManager</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableLxssManager.ps1">Download Script: Configure-DisableLxssManager.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableLxssManager.ps1
# Description: Disables the unnecessary LxssManager (LxssManager) service.

Write-Host "Applying hardening requirement: Disable LxssManager service..." -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-LxssManagerStatus.ps1">Download Script: Get-LxssManagerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-LxssManagerStatus.ps1
# Description: Audits the startup configuration of LxssManager (LxssManager) service.

Write-Host "--- Auditing LxssManager (LxssManager) Service ---" -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableLxssManager.ps1
# Description: Disables the unnecessary LxssManager (LxssManager) service.

Write-Host "Applying hardening requirement: Disable LxssManager service..." -ForegroundColor Cyan

$ServiceName = "LxssManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8040" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-041" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-041] Disable Microsoft FTP Service (FTPSVC)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-041](../../07-paws/services/disable-ftpsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-ftpsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Microsoft FTP Service (<xhtml:code>FTPSVC</xhtml:code>) is an IIS server component that provides File Transfer Protocol (FTP) hosting services over TCP port 21.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Microsoft FTP Service</xhtml:code> (<xhtml:code>FTPSVC</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableFTPSVC.ps1">Download Script: Configure-DisableFTPSVC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableFTPSVC.ps1
# Description: Disables the unnecessary Microsoft FTP Service (FTPSVC) service.

Write-Host "Applying hardening requirement: Disable Microsoft FTP Service service..." -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-FTPSVCStatus.ps1">Download Script: Get-FTPSVCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-FTPSVCStatus.ps1
# Description: Audits the startup configuration of Microsoft FTP Service (FTPSVC) service.

Write-Host "--- Auditing Microsoft FTP Service (FTPSVC) Service ---" -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableFTPSVC.ps1
# Description: Disables the unnecessary Microsoft FTP Service (FTPSVC) service.

Write-Host "Applying hardening requirement: Disable Microsoft FTP Service service..." -ForegroundColor Cyan

$ServiceName = "FTPSVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8041" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-042" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-042] Disable OpenSSH SSH Server Service (sshd)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-042](../../07-paws/services/disable-sshd.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-sshd.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The OpenSSH SSH Server service (<xhtml:code>sshd</xhtml:code>) provides inbound secure shell access, interactive command-line terminal hosting (cmd/PowerShell), and secure file transfer (SFTP/SCP) over TCP port 22.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>OpenSSH SSH Server</xhtml:code> (<xhtml:code>sshd</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablesshd.ps1">Download Script: Configure-Disablesshd.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablesshd.ps1
# Description: Disables the unnecessary OpenSSH SSH Server (sshd) service.

Write-Host "Applying hardening requirement: Disable OpenSSH SSH Server service..." -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-sshdStatus.ps1">Download Script: Get-sshdStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-sshdStatus.ps1
# Description: Audits the startup configuration of OpenSSH SSH Server (sshd) service.

Write-Host "--- Auditing OpenSSH SSH Server (sshd) Service ---" -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablesshd.ps1
# Description: Disables the unnecessary OpenSSH SSH Server (sshd) service.

Write-Host "Applying hardening requirement: Disable OpenSSH SSH Server service..." -ForegroundColor Cyan

$ServiceName = "sshd"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8042" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-043" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-043] Disable Remote Procedure Call (RPC) Locator Service (RpcLocator)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-043](../../07-paws/services/disable-rpclocator.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-rpclocator.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Remote Procedure Call (RPC) Locator service (<xhtml:code>RpcLocator</xhtml:code>) manages the legacy RPC name service database, originally designed in early Windows NT architectures to allow RPC server applications to publish interface bindings and RPC clients to discover those interfaces by name across network domains.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Remote Procedure Call (RPC) Locator</xhtml:code> (<xhtml:code>RpcLocator</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableRpcLocator.ps1">Download Script: Configure-DisableRpcLocator.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableRpcLocator.ps1
# Description: Disables the unnecessary Remote Procedure Call (RPC) Locator (RpcLocator) service.

Write-Host "Applying hardening requirement: Disable Remote Procedure Call (RPC) Locator service..." -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-RpcLocatorStatus.ps1">Download Script: Get-RpcLocatorStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-RpcLocatorStatus.ps1
# Description: Audits the startup configuration of Remote Procedure Call (RPC) Locator (RpcLocator) service.

Write-Host "--- Auditing Remote Procedure Call (RPC) Locator (RpcLocator) Service ---" -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableRpcLocator.ps1
# Description: Disables the unnecessary Remote Procedure Call (RPC) Locator (RpcLocator) service.

Write-Host "Applying hardening requirement: Disable Remote Procedure Call (RPC) Locator service..." -ForegroundColor Cyan

$ServiceName = "RpcLocator"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8043" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-044" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-044] Disable Routing and Remote Access Service (RemoteAccess)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-044](../../07-paws/services/disable-remoteaccess.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-remoteaccess.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Routing and Remote Access Service (<xhtml:code>RemoteAccess</xhtml:code> / RRAS) provides multi-protocol LAN-to-LAN routing, Network Address Translation (NAT), dial-up networking, and VPN server capabilities (PPTP, L2TP, SSTP, IKEv2).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Routing and Remote Access</xhtml:code> (<xhtml:code>RemoteAccess</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableRemoteAccess.ps1">Download Script: Configure-DisableRemoteAccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableRemoteAccess.ps1
# Description: Disables the unnecessary Routing and Remote Access (RemoteAccess) service.

Write-Host "Applying hardening requirement: Disable Routing and Remote Access service..." -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-RemoteAccessStatus.ps1">Download Script: Get-RemoteAccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-RemoteAccessStatus.ps1
# Description: Audits the startup configuration of Routing and Remote Access (RemoteAccess) service.

Write-Host "--- Auditing Routing and Remote Access (RemoteAccess) Service ---" -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableRemoteAccess.ps1
# Description: Disables the unnecessary Routing and Remote Access (RemoteAccess) service.

Write-Host "Applying hardening requirement: Disable Routing and Remote Access service..." -ForegroundColor Cyan

$ServiceName = "RemoteAccess"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8044" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-045" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-045] Disable Simple TCP/IP Services (simptcp)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-045](../../07-paws/services/disable-simptcp.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-simptcp.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Simple TCP/IP Services (<xhtml:code>simptcp</xhtml:code>) implement a suite of legacy diagnostic protocols conceived in the 1980s over both TCP and UDP: Echo (port 7, RFC 862), Discard (port 9, RFC 863), Character Generator / Chargen (port 19, RFC 864), Daytime (port 13, RFC 867), and Quote of the Day / QOTD (port 17, RFC 865).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Simple TCP/IP Services</xhtml:code> (<xhtml:code>simptcp</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablesimptcp.ps1">Download Script: Configure-Disablesimptcp.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablesimptcp.ps1
# Description: Disables the unnecessary Simple TCP/IP Services (simptcp) service.

Write-Host "Applying hardening requirement: Disable Simple TCP/IP Services service..." -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-simptcpStatus.ps1">Download Script: Get-simptcpStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-simptcpStatus.ps1
# Description: Audits the startup configuration of Simple TCP/IP Services (simptcp) service.

Write-Host "--- Auditing Simple TCP/IP Services (simptcp) Service ---" -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablesimptcp.ps1
# Description: Disables the unnecessary Simple TCP/IP Services (simptcp) service.

Write-Host "Applying hardening requirement: Disable Simple TCP/IP Services service..." -ForegroundColor Cyan

$ServiceName = "simptcp"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8045" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-046" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-046] Disable Special Administration Console Helper Service (sacsvr)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-046](../../07-paws/services/disable-sacsvr.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-sacsvr.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Special Administration Console (SAC) Helper service (<xhtml:code>sacsvr</xhtml:code>) supports Emergency Management Services (EMS), an out-of-band management architecture developed for headless Windows Server hardware to allow remote diagnostic console access over physical or virtual serial (COM) ports.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Special Administration Console Helper</xhtml:code> (<xhtml:code>sacsvr</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disablesacsvr.ps1">Download Script: Configure-Disablesacsvr.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disablesacsvr.ps1
# Description: Disables the unnecessary Special Administration Console Helper (sacsvr) service.

Write-Host "Applying hardening requirement: Disable Special Administration Console Helper service..." -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-sacsvrStatus.ps1">Download Script: Get-sacsvrStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-sacsvrStatus.ps1
# Description: Audits the startup configuration of Special Administration Console Helper (sacsvr) service.

Write-Host "--- Auditing Special Administration Console Helper (sacsvr) Service ---" -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disablesacsvr.ps1
# Description: Disables the unnecessary Special Administration Console Helper (sacsvr) service.

Write-Host "Applying hardening requirement: Disable Special Administration Console Helper service..." -ForegroundColor Cyan

$ServiceName = "sacsvr"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8046" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-047" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-047] Disable SSDP Discovery Service (SSDPSRV)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-047](../../07-paws/services/disable-ssdpsrv.md); for Domain Controllers, refer to [REQ-DC-060](../../02-domain-controllers/services/disable-ssdpsrv.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-ssdpsrv.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Simple Service Discovery Protocol (SSDP) Discovery service (<xhtml:code>SSDPSRV</xhtml:code>) listens on UDP port 1900 multicast (<xhtml:code>239.255.255.250</xhtml:code> for IPv4 and <xhtml:code>[FF02::C]</xhtml:code> / <xhtml:code>[FF05::C]</xhtml:code> for IPv6) to discover Universal Plug and Play (UPnP) networked devices such as consumer printers, residential gateways, smart displays, and media renderers.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>SSDP Discovery</xhtml:code> (<xhtml:code>SSDPSRV</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableSSDPSRV.ps1">Download Script: Configure-DisableSSDPSRV.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-SSDPSRVStatus.ps1">Download Script: Get-SSDPSRVStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-SSDPSRVStatus.ps1
# Description: Audits the startup configuration of SSDP Discovery (SSDPSRV) service.

Write-Host "--- Auditing SSDP Discovery (SSDPSRV) Service ---" -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableSSDPSRV.ps1
# Description: Disables the unnecessary SSDP Discovery (SSDPSRV) service.

Write-Host "Applying hardening requirement: Disable SSDP Discovery service..." -ForegroundColor Cyan

$ServiceName = "SSDPSRV"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8047" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-048" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-048] Disable UPnP Device Host Service (upnphost)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-048](../../07-paws/services/disable-upnphost.md); for Domain Controllers, refer to [REQ-DC-063](../../02-domain-controllers/services/disable-upnphost.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-upnphost.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The UPnP Device Host service (<xhtml:code>upnphost</xhtml:code>) enables a Windows endpoint to announce, configure, and host dynamic Universal Plug and Play (UPnP) devices and control points. When software components or peripherals register with <xhtml:code>upnphost</xhtml:code>, the service publishes XML device descriptions and listens on local HTTP endpoints to process incoming UPnP SOAP control actions.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>UPnP Device Host</xhtml:code> (<xhtml:code>upnphost</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disableupnphost.ps1">Download Script: Configure-Disableupnphost.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disableupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-upnphostStatus.ps1">Download Script: Get-upnphostStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-upnphostStatus.ps1
# Description: Audits the startup configuration of UPnP Device Host (upnphost) service.

Write-Host "--- Auditing UPnP Device Host (upnphost) Service ---" -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disableupnphost.ps1
# Description: Disables the unnecessary UPnP Device Host (upnphost) service.

Write-Host "Applying hardening requirement: Disable UPnP Device Host service..." -ForegroundColor Cyan

$ServiceName = "upnphost"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8048" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-049" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-049] Disable Web Management Service (WMSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-049](../../07-paws/services/disable-wmsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-wmsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Web Management Service (<xhtml:code>WMSvc</xhtml:code>) facilitates remote web server administration for Internet Information Services (IIS), listening for incoming remote management connections over HTTPS TCP port 8172.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Web Management Service</xhtml:code> (<xhtml:code>WMSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWMSvc.ps1">Download Script: Configure-DisableWMSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWMSvc.ps1
# Description: Disables the unnecessary Web Management Service (WMSvc) service.

Write-Host "Applying hardening requirement: Disable Web Management Service service..." -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WMSvcStatus.ps1">Download Script: Get-WMSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WMSvcStatus.ps1
# Description: Audits the startup configuration of Web Management Service (WMSvc) service.

Write-Host "--- Auditing Web Management Service (WMSvc) Service ---" -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWMSvc.ps1
# Description: Disables the unnecessary Web Management Service (WMSvc) service.

Write-Host "Applying hardening requirement: Disable Web Management Service service..." -ForegroundColor Cyan

$ServiceName = "WMSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8049" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-050" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-050] Disable Windows Media Player Network Sharing Service (WMPNetworkSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-050](../../07-paws/services/disable-wmpnetworksvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-wmpnetworksvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Media Player Network Sharing Service (<xhtml:code>WMPNetworkSvc</xhtml:code>, hosted by <xhtml:code>wmpnetwk.exe</xhtml:code> or <xhtml:code>svchost.exe</xhtml:code>) shares Windows Media Player multimedia libraries (audio, video, playlists) with other network media players and control devices over Universal Plug and Play (UPnP) and Digital Living Network Alliance (DLNA) protocols.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Windows Media Player Network Sharing Service</xhtml:code> (<xhtml:code>WMPNetworkSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableWMPNetworkSvc.ps1">Download Script: Configure-DisableWMPNetworkSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableWMPNetworkSvc.ps1
# Description: Disables the unnecessary Windows Media Player Network Sharing Service (WMPNetworkSvc) service.

Write-Host "Applying hardening requirement: Disable Windows Media Player Network Sharing Service service..." -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-WMPNetworkSvcStatus.ps1">Download Script: Get-WMPNetworkSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-WMPNetworkSvcStatus.ps1
# Description: Audits the startup configuration of Windows Media Player Network Sharing Service (WMPNetworkSvc) service.

Write-Host "--- Auditing Windows Media Player Network Sharing Service (WMPNetworkSvc) Service ---" -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableWMPNetworkSvc.ps1
# Description: Disables the unnecessary Windows Media Player Network Sharing Service (WMPNetworkSvc) service.

Write-Host "Applying hardening requirement: Disable Windows Media Player Network Sharing Service service..." -ForegroundColor Cyan

$ServiceName = "WMPNetworkSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8050" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-051" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-051] Disable Windows Mobile Hotspot Service (icssvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-051](../../07-paws/services/disable-icssvc.md); for Domain Controllers, refer to [REQ-DC-072](../../02-domain-controllers/services/disable-icssvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-icssvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Windows Mobile Hotspot Service (<xhtml:code>icssvc</xhtml:code>) manages software-based wireless access points (SoftAP) and connection tethering features, allowing an endpoint to share its Ethernet, Wi-Fi, or cellular connection with external wireless devices.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Windows Mobile Hotspot Service</xhtml:code> (<xhtml:code>icssvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-Disableicssvc.ps1">Download Script: Configure-Disableicssvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-Disableicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-icssvcStatus.ps1">Download Script: Get-icssvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-icssvcStatus.ps1
# Description: Audits the startup configuration of Windows Mobile Hotspot Service (icssvc) service.

Write-Host "--- Auditing Windows Mobile Hotspot Service (icssvc) Service ---" -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-Disableicssvc.ps1
# Description: Disables the unnecessary Windows Mobile Hotspot Service (icssvc) service.

Write-Host "Applying hardening requirement: Disable Windows Mobile Hotspot Service service..." -ForegroundColor Cyan

$ServiceName = "icssvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8051" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-052" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-052] Disable World Wide Web Publishing Service (W3SVC)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-052](../../07-paws/services/disable-w3svc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-w3svc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The World Wide Web Publishing Service (<xhtml:code>W3SVC</xhtml:code>) is the core Internet Information Services (IIS) HTTP/HTTPS web server engine. It manages HTTP listeners, routes web traffic to <xhtml:code>w3wp.exe</xhtml:code> worker processes, and hosts ASP.NET, PHP, and static web content over TCP ports 80 and 443.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>World Wide Web Publishing Service</xhtml:code> (<xhtml:code>W3SVC</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableW3SVC.ps1">Download Script: Configure-DisableW3SVC.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableW3SVC.ps1
# Description: Disables the unnecessary World Wide Web Publishing Service (W3SVC) service.

Write-Host "Applying hardening requirement: Disable World Wide Web Publishing Service service..." -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-W3SVCStatus.ps1">Download Script: Get-W3SVCStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-W3SVCStatus.ps1
# Description: Audits the startup configuration of World Wide Web Publishing Service (W3SVC) service.

Write-Host "--- Auditing World Wide Web Publishing Service (W3SVC) Service ---" -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableW3SVC.ps1
# Description: Disables the unnecessary World Wide Web Publishing Service (W3SVC) service.

Write-Host "Applying hardening requirement: Disable World Wide Web Publishing Service service..." -ForegroundColor Cyan

$ServiceName = "W3SVC"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8052" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-053" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-053] Disable Xbox Accessory Management Service (XboxGipSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-053](../../07-paws/services/disable-xboxgipsvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-xboxgipsvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Accessory Management Service (<xhtml:code>XboxGipSvc</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XboxGipSvc.dll</xhtml:code>) manages connected Xbox peripherals, gamepads, steering wheels, headsets, and consumer wireless dongles by interfacing with the Xbox Game Input Protocol (GIP) kernel driver stack (<xhtml:code>xboxgip.sys</xhtml:code>).</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Accessory Management Service</xhtml:code> (<xhtml:code>XboxGipSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXboxGipSvc.ps1">Download Script: Configure-DisableXboxGipSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXboxGipSvc.ps1
# Description: Disables the unnecessary Xbox Accessory Management Service (XboxGipSvc) service.

Write-Host "Applying hardening requirement: Disable Xbox Accessory Management Service service..." -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XboxGipSvcStatus.ps1">Download Script: Get-XboxGipSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XboxGipSvcStatus.ps1
# Description: Audits the startup configuration of Xbox Accessory Management Service (XboxGipSvc) service.

Write-Host "--- Auditing Xbox Accessory Management Service (XboxGipSvc) Service ---" -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXboxGipSvc.ps1
# Description: Disables the unnecessary Xbox Accessory Management Service (XboxGipSvc) service.

Write-Host "Applying hardening requirement: Disable Xbox Accessory Management Service service..." -ForegroundColor Cyan

$ServiceName = "XboxGipSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8053" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-054" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-054] Disable Xbox Live Auth Manager (XblAuthManager)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-054](../../07-paws/services/disable-xblauthmanager.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-xblauthmanager.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Auth Manager (<xhtml:code>XblAuthManager</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XblAuthManager.dll</xhtml:code>) provides programmatic authentication and token brokering services for consumer Microsoft Accounts (MSA) and the Xbox Live cloud gaming platform.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Auth Manager</xhtml:code> (<xhtml:code>XblAuthManager</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXblAuthManager.ps1">Download Script: Configure-DisableXblAuthManager.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XblAuthManagerStatus.ps1">Download Script: Get-XblAuthManagerStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XblAuthManagerStatus.ps1
# Description: Audits the startup configuration of Xbox Live Auth Manager (XblAuthManager) service.

Write-Host "--- Auditing Xbox Live Auth Manager (XblAuthManager) Service ---" -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXblAuthManager.ps1
# Description: Disables the unnecessary Xbox Live Auth Manager (XblAuthManager) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Auth Manager service..." -ForegroundColor Cyan

$ServiceName = "XblAuthManager"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8054" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-055" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-055] Disable Xbox Live Game Save Service (XblGameSave)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-055](../../07-paws/services/disable-xblgamesave.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-xblgamesave.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Game Save Service (<xhtml:code>XblGameSave</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XblGameSave.dll</xhtml:code>) manages background synchronization of game state, telemetry, and save container files between the local workstation file system and Microsoft Xbox Live consumer cloud storage.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Game Save</xhtml:code> (<xhtml:code>XblGameSave</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXblGameSave.ps1">Download Script: Configure-DisableXblGameSave.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XblGameSaveStatus.ps1">Download Script: Get-XblGameSaveStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XblGameSaveStatus.ps1
# Description: Audits the startup configuration of Xbox Live Game Save (XblGameSave) service.

Write-Host "--- Auditing Xbox Live Game Save (XblGameSave) Service ---" -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXblGameSave.ps1
# Description: Disables the unnecessary Xbox Live Game Save (XblGameSave) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Game Save service..." -ForegroundColor Cyan

$ServiceName = "XblGameSave"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8055" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-056" severity="medium" weight="10.0" selected="false">
        <title>[REQ-END-056] Disable Xbox Live Networking Service (XboxNetApiSvc)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-056](../../07-paws/services/disable-xboxnetapisvc.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-xboxnetapisvc.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The Xbox Live Networking Service (<xhtml:code>XboxNetApiSvc</xhtml:code>, hosted in <xhtml:code>svchost.exe</xhtml:code> via <xhtml:code>XboxNetApiSvc.dll</xhtml:code>) provides network interface management, peer-to-peer session establishment, and NAT traversal capabilities for Xbox Live multiplayer, party chat, and Windows gaming network APIs.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the target endpoints GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>Xbox Live Networking Service</xhtml:code> (<xhtml:code>XboxNetApiSvc</xhtml:code>), double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableXboxNetApiSvc.ps1">Download Script: Configure-DisableXboxNetApiSvc.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableXboxNetApiSvc.ps1
# Description: Disables the unnecessary Xbox Live Networking Service (XboxNetApiSvc) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Networking Service service..." -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup type of this unnecessary service:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-XboxNetApiSvcStatus.ps1">Download Script: Get-XboxNetApiSvcStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-XboxNetApiSvcStatus.ps1
# Description: Audits the startup configuration of Xbox Live Networking Service (XboxNetApiSvc) service.

Write-Host "--- Auditing Xbox Live Networking Service (XboxNetApiSvc) Service ---" -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableXboxNetApiSvc.ps1
# Description: Disables the unnecessary Xbox Live Networking Service (XboxNetApiSvc) service.

Write-Host "Applying hardening requirement: Disable Xbox Live Networking Service service..." -ForegroundColor Cyan

$ServiceName = "XboxNetApiSvc"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8056" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-177" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-177] Disable WebClient Service (WebClient)</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 client workstations and member servers. <xhtml:em>(For Tier 0 Privileged Access Workstations, refer to tightened baseline [REQ-PAW-166](../../07-paws/services/disable-webclient.md); for Domain Controllers, refer to [REQ-DC-146](../../02-domain-controllers/services/disable-webclient.md)).</xhtml:em>
            </xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10 (all supported editions), Windows 11 Enterprise/Pro, Windows Server 2016, 2019, 2022, and 2025.</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/services/disable-webclient.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>The WebClient service (<xhtml:code>WebClient</xhtml:code>, driven by <xhtml:code>davclnt.sys</xhtml:code>) enables Windows programs to create, access, and modify remote files on Internet-based web servers using the Web Distributed Authoring and Versioning (WebDAV) protocol over HTTP and HTTPS.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Open the <xhtml:strong>Group Policy Management Console</xhtml:strong> (<xhtml:code>gpmc.msc</xhtml:code>).</xhtml:li>
            <xhtml:li>Edit the Endpoint GPO (e.g., <xhtml:code>GPO_Hardening_Endpoints</xhtml:code>).</xhtml:li>
            <xhtml:li>Navigate to:</xhtml:li>
            <xhtml:li>
              <xhtml:code>Computer Configuration\Policies\Windows Settings\Security Settings\System Services</xhtml:code>
            </xhtml:li>
            <xhtml:li>Locate <xhtml:code>WebClient</xhtml:code>, double-click to define the policy, and select <xhtml:strong>Disabled</xhtml:strong>.</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-DisableEndWebClient.ps1">Download Script: Configure-DisableEndWebClient.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-DisableEndWebClient.ps1
# Description: Disables the unnecessary WebClient service on standard client endpoints and member servers.

Write-Host "Applying hardening requirement: Disable WebClient service on Endpoint..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To verify the startup configuration of the WebClient service on the endpoint:</xhtml:em>
          </xhtml:p>
          <xhtml:p>
            <xhtml:a href="../audit_scripts/Get-EndWebClientStatus.ps1">Download Script: Get-EndWebClientStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndWebClientStatus.ps1
# Description: Audits the startup configuration of the WebClient service on the local endpoint.

Write-Host "--- Auditing WebClient Service on Endpoint ---" -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"
$IsVulnerable = $false

if (Test-Path -Path $RegPath) {
    $StartVal = Get-ItemProperty -Path $RegPath -Name "Start" -ErrorAction SilentlyContinue
    if ($null -ne $StartVal) {
        $Start = $StartVal.Start
        if ($Start -eq 4) {
            Write-Host "[+] Service '$($ServiceName)' is secure (Disabled)." -ForegroundColor Green
        } else {
            Write-Host "[!] VULNERABLE: Service '$($ServiceName)' startup type is not Disabled (Start value is $($Start))." -ForegroundColor Red
            $IsVulnerable = $true
        }
    } else {
        Write-Host "[!] VULNERABLE: Service '$($ServiceName)' exists but Start registry value is missing." -ForegroundColor Red
        $IsVulnerable = $true
    }
} else {
    Write-Host "[+] Service '$($ServiceName)' is not installed (Secure)." -ForegroundColor Green
}

if ($IsVulnerable) {
    Write-Host "Audit Result: VULNERABLE" -ForegroundColor Red
    exit 1
} else {
    Write-Host "Audit Result: SECURE" -ForegroundColor Green
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-DisableEndWebClient.ps1
# Description: Disables the unnecessary WebClient service on standard client endpoints and member servers.

Write-Host "Applying hardening requirement: Disable WebClient service on Endpoint..." -ForegroundColor Cyan

$ServiceName = "WebClient"
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($ServiceName)"

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -ne $Service) {
    if ($Service.StartType -ne "Disabled") {
        if ($Service.Status -eq "Running") {
            Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue | Out-Null
        }
        Set-Service -Name $ServiceName -StartupType Disabled -ErrorAction SilentlyContinue | Out-Null
        Write-Host "[+] Service '$($ServiceName)' stopped and disabled." -ForegroundColor Green
    } else {
        Write-Host "[~] Service '$($ServiceName)' is already disabled." -ForegroundColor Gray
    }
} else {
    Write-Host "[~] Service '$($ServiceName)' is not installed." -ForegroundColor Gray
}

if (Test-Path -Path $RegPath) {
    Set-ItemProperty -Path $RegPath -Name "Start" -Value 4 -Type DWord -ErrorAction SilentlyContinue | Out-Null
    Write-Host "[+] Registry Start value set to 4 (Disabled) for service '$($ServiceName)'." -ForegroundColor Green
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8177" />
        </check>
      </Rule>
    </Group>
    <Group id="xccdf_org.adhardening.benchmarks_group_Module_8__Endpoint_Hardening_Advanced_Security_Audit_Policies">
      <title>Advanced Security Audit Policies</title>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-141" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-141] Audit Policy: Advanced Audit Policy Overrides for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-audit-override.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Enforcing advanced audit policy overrides prevents legacy category settings from overriding refined subcategory policies, and disabling verbose Kerberos logging ensures that event logs are not flooded with diagnostic events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\System\CurrentControlSet\Control\Lsa\ SCENoApplyLegacyAuditPolicy</xhtml:code> = <xhtml:code>1</xhtml:code> (DWord)</xhtml:li>
            <xhtml:li>* Registry: <xhtml:code>HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters\ LogLevel</xhtml:code> = <xhtml:code>0</xhtml:code> (DWord)</xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAuditoverride.ps1">Download Script: Configure-EndAuditAuditoverride.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditAuditoverrideStatus.ps1">Download Script: Get-EndAuditAuditoverrideStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAuditoverrideStatus.ps1
$script:Vulnerable = $false

# Audit Registry: SCENoApplyLegacyAuditPolicy
$RegVal = Get-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.SCENoApplyLegacyAuditPolicy -ne 1) {
    $script:Vulnerable = $true
}

# Audit Registry: LogLevel
$RegVal = Get-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -ErrorAction SilentlyContinue
if (-not $RegVal -or $RegVal.LogLevel -ne 0) {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAuditoverride.ps1
Write-Host "Applying Audit Policy category: audit-override..." -ForegroundColor Cyan

# Set Registry Override: SCENoApplyLegacyAuditPolicy
if (-not (Test-Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa")) { New-Item -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\System\CurrentControlSet\Control\Lsa" -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force
Write-Host "    Enforced SCENoApplyLegacyAuditPolicy = 1" -ForegroundColor Green

# Set Registry Override: LogLevel
if (-not (Test-Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters")) { New-Item -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Force | Out-Null }
Set-ItemProperty -Path "reg:\HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" -Name "LogLevel" -Value 0 -Type DWord -Force
Write-Host "    Enforced LogLevel = 0" -ForegroundColor Green</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8141" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-142" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-142] Audit Policy: Account Logon Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-account-logon.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account logon events captures authentication requests processed by the local system or the domain controller, which is critical for identifying Kerberoasting, NTLM relaying, and brute-force attempts.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Credential Validation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAccountlogon.ps1">Download Script: Configure-EndAuditAccountlogon.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditAccountlogonStatus.ps1">Download Script: Get-EndAuditAccountlogonStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAccountlogonStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Credential Validation
$RawOutput = auditpol.exe /get /subcategory:"Credential Validation" /r
if ($RawOutput -notmatch ",Credential Validation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAccountlogon.ps1
Write-Host "Applying Audit Policy category: account-logon..." -ForegroundColor Cyan

# Set Audit Subcategory: Credential Validation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Credential Validation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Credential Validation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Credential Validation. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8142" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-143" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-143] Audit Policy: Account Management Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-account-management.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing account management logs security principal modifications (creations, deletions, password resets, group modifications) to detect privilege escalation attempts on domain or local administrative groups.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>User Account Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security Group Management</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Account Management Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditAccountmanagement.ps1">Download Script: Configure-EndAuditAccountmanagement.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditAccountmanagementStatus.ps1">Download Script: Get-EndAuditAccountmanagementStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditAccountmanagementStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: User Account Management
$RawOutput = auditpol.exe /get /subcategory:"User Account Management" /r
if ($RawOutput -notmatch ",User Account Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security Group Management
$RawOutput = auditpol.exe /get /subcategory:"Security Group Management" /r
if ($RawOutput -notmatch ",Security Group Management,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Account Management Events
$RawOutput = auditpol.exe /get /subcategory:"Other Account Management Events" /r
if ($RawOutput -notmatch ",Other Account Management Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditAccountmanagement.ps1
Write-Host "Applying Audit Policy category: account-management..." -ForegroundColor Cyan

# Set Audit Subcategory: User Account Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"User Account Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory User Account Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory User Account Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security Group Management
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security Group Management`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security Group Management to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security Group Management. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Account Management Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Account Management Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Account Management Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Account Management Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8143" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-144" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-144] Audit Policy: Detailed Tracking Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-detailed-tracking.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Detailed tracking records process creations and device arrivals to ensure EDR/SIEM visibility into executable command lines and hardware plug events.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Process Creation</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>DPAPI Activity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>PNP Activity</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditDetailedtracking.ps1">Download Script: Configure-EndAuditDetailedtracking.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditDetailedtrackingStatus.ps1">Download Script: Get-EndAuditDetailedtrackingStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditDetailedtrackingStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Process Creation
$RawOutput = auditpol.exe /get /subcategory:"Process Creation" /r
if ($RawOutput -notmatch ",Process Creation,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: DPAPI Activity
$RawOutput = auditpol.exe /get /subcategory:"DPAPI Activity" /r
if ($RawOutput -notmatch ",DPAPI Activity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: PNP Activity
$RawOutput = auditpol.exe /get /subcategory:"PNP Activity" /r
if ($RawOutput -notmatch ",PNP Activity,.*,Success") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditDetailedtracking.ps1
Write-Host "Applying Audit Policy category: detailed-tracking..." -ForegroundColor Cyan

# Set Audit Subcategory: Process Creation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Process Creation`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Process Creation to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Process Creation. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: DPAPI Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"DPAPI Activity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory DPAPI Activity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory DPAPI Activity. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: PNP Activity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"PNP Activity`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory PNP Activity to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory PNP Activity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8144" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-146" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-146] Audit Policy: Logon and Logoff Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-logon-logoff.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing logon/logoff events monitors administrative session states, special elevations, and failed logon attempts, which is critical for finding unauthorized remote access or lateral movement.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Logoff</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Special Logon</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Account Lockout</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Logon/Logoff Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditLogonlogoff.ps1">Download Script: Configure-EndAuditLogonlogoff.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditLogonlogoffStatus.ps1">Download Script: Get-EndAuditLogonlogoffStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditLogonlogoffStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Logon
$RawOutput = auditpol.exe /get /subcategory:"Logon" /r
if ($RawOutput -notmatch ",Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Logoff
$RawOutput = auditpol.exe /get /subcategory:"Logoff" /r
if ($RawOutput -notmatch ",Logoff,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Special Logon
$RawOutput = auditpol.exe /get /subcategory:"Special Logon" /r
if ($RawOutput -notmatch ",Special Logon,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Account Lockout
$RawOutput = auditpol.exe /get /subcategory:"Account Lockout" /r
if ($RawOutput -notmatch ",Account Lockout,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Logon/Logoff Events
$RawOutput = auditpol.exe /get /subcategory:"Other Logon/Logoff Events" /r
if ($RawOutput -notmatch ",Other Logon/Logoff Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditLogonlogoff.ps1
Write-Host "Applying Audit Policy category: logon-logoff..." -ForegroundColor Cyan

# Set Audit Subcategory: Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Logoff
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Logoff`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Logoff to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Logoff. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Special Logon
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Special Logon`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Special Logon to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Special Logon. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Account Lockout
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Account Lockout`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Account Lockout to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Account Lockout. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Logon/Logoff Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Logon/Logoff Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Logon/Logoff Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Logon/Logoff Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8146" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-147" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-147] Audit Policy: Object Access Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-object-access.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing object access (files, registry keys, and shares) helps monitor unauthorized modifications to system configuration files and access to restricted shares.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Registry</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>File Share</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Detailed File Share</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Handle Manipulation</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditObjectaccess.ps1">Download Script: Configure-EndAuditObjectaccess.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditObjectaccessStatus.ps1">Download Script: Get-EndAuditObjectaccessStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditObjectaccessStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Registry
$RawOutput = auditpol.exe /get /subcategory:"Registry" /r
if ($RawOutput -notmatch ",Registry,.*,Failure") {
    $script:Vulnerable = $true
}

# Audit Subcategory: File Share
$RawOutput = auditpol.exe /get /subcategory:"File Share" /r
if ($RawOutput -notmatch ",File Share,.*,Failure") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Detailed File Share
$RawOutput = auditpol.exe /get /subcategory:"Detailed File Share" /r
if ($RawOutput -notmatch ",Detailed File Share,.*,Failure") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Handle Manipulation
$RawOutput = auditpol.exe /get /subcategory:"Handle Manipulation" /r
if ($RawOutput -notmatch ",Handle Manipulation,.*,Failure") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditObjectaccess.ps1
Write-Host "Applying Audit Policy category: object-access..." -ForegroundColor Cyan

# Set Audit Subcategory: Registry
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Registry`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Registry to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Registry. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Detailed File Share
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Detailed File Share`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Detailed File Share to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Detailed File Share. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Handle Manipulation
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Handle Manipulation`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Handle Manipulation to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Handle Manipulation. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8147" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-148" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-148] Audit Policy: Policy Change Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-policy-change.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing policy changes tracks attempts to modify authorization policies, auditing configuration changes, or firewall rule alterations to hide adversarial tracks.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authentication Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Authorization Policy Change</xhtml:code> -&gt; <xhtml:code>Success</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>MPSSVC Rule-Level Policy Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other Policy Change Events</xhtml:code> -&gt; <xhtml:code>Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditPolicychange.ps1">Download Script: Configure-EndAuditPolicychange.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditPolicychangeStatus.ps1">Download Script: Get-EndAuditPolicychangeStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditPolicychangeStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Policy Change" /r
if ($RawOutput -notmatch ",Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authentication Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authentication Policy Change" /r
if ($RawOutput -notmatch ",Authentication Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Authorization Policy Change
$RawOutput = auditpol.exe /get /subcategory:"Authorization Policy Change" /r
if ($RawOutput -notmatch ",Authorization Policy Change,.*,Success") {
    $script:Vulnerable = $true
}

# Audit Subcategory: MPSSVC Rule-Level Policy Change
$RawOutput = auditpol.exe /get /subcategory:"MPSSVC Rule-Level Policy Change" /r
if ($RawOutput -notmatch ",MPSSVC Rule-Level Policy Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Other Policy Change Events
$RawOutput = auditpol.exe /get /subcategory:"Other Policy Change Events" /r
if ($RawOutput -notmatch ",Other Policy Change Events,.*,Failure") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditPolicychange.ps1
Write-Host "Applying Audit Policy category: policy-change..." -ForegroundColor Cyan

# Set Audit Subcategory: Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authentication Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authentication Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authentication Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authentication Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Authorization Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Authorization Policy Change`" /success:enable /failure:disable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Authorization Policy Change to Success" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Authorization Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: MPSSVC Rule-Level Policy Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"MPSSVC Rule-Level Policy Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory MPSSVC Rule-Level Policy Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory MPSSVC Rule-Level Policy Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Other Policy Change Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other Policy Change Events`" /success:disable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other Policy Change Events to Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other Policy Change Events. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8148" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-149" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-149] Audit Policy: Privilege Use Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-privilege-use.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing sensitive privilege use logs attempts by processes or users to exercise rights like ActAsPartOfTypeOperatingSystem or LoadDrivers, identifying potential privilege escalations.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Sensitive Privilege Use</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditPrivilegeuse.ps1">Download Script: Configure-EndAuditPrivilegeuse.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditPrivilegeuseStatus.ps1">Download Script: Get-EndAuditPrivilegeuseStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditPrivilegeuseStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Sensitive Privilege Use
$RawOutput = auditpol.exe /get /subcategory:"Sensitive Privilege Use" /r
if ($RawOutput -notmatch ",Sensitive Privilege Use,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditPrivilegeuse.ps1
Write-Host "Applying Audit Policy category: privilege-use..." -ForegroundColor Cyan

# Set Audit Subcategory: Sensitive Privilege Use
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Sensitive Privilege Use`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Sensitive Privilege Use to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Sensitive Privilege Use. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8149" />
        </check>
      </Rule>
      <Rule id="xccdf_org.adhardening.benchmarks_rule_REQ-END-150" severity="high" weight="10.0" selected="false">
        <title>[REQ-END-150] Audit Policy: System Events Auditing for Endpoints</title>
        <description>
          <xhtml:p>
            <xhtml:strong>Target Scope:</xhtml:strong>
          </xhtml:p>
          <xhtml:ul>
            <xhtml:li>
              <xhtml:strong>Applicable Systems</xhtml:strong>: Tier 2 Client Workstations</xhtml:li>
            <xhtml:li>
              <xhtml:strong>Operating Systems</xhtml:strong>: Windows 10/11 Enterprise/Professional</xhtml:li>
          </xhtml:ul>
          <xhtml:p>
            <xhtml:strong>File Path: </xhtml:strong>
            <xhtml:code>08-endpoints/audit-policy/configure-end-audit-system-events.md</xhtml:code>
          </xhtml:p>
        </description>
        <rationale>
          <xhtml:p>Auditing system security extensions, integrity violations, and driver arrivals monitors boot health and tampering of host security services.</xhtml:p>
        </rationale>
        <fixtext>
          <xhtml:h3>Option A: Group Policy Object (GPO) Configuration (Preferred)</xhtml:h3>
          <xhtml:ol>
            <xhtml:li>Configure Advanced Audit Policy subcategory or registry override preferences matching:</xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Other System Events</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security State Change</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>Security System Extension</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
            <xhtml:li>* Subcategory: <xhtml:code>System Integrity</xhtml:code> -&gt; <xhtml:code>Success and Failure</xhtml:code>
            </xhtml:li>
          </xhtml:ol>
          <xhtml:hr />
          <xhtml:h3>Option B: PowerShell &amp; Registry Configuration (Remediation / Non-GPO)</xhtml:h3>
          <xhtml:p>
            <xhtml:a href="../implementation_scripts/Configure-EndAuditSystemevents.ps1">Download Script: Configure-EndAuditSystemevents.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Configure-EndAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}

</xhtml:code>
          </xhtml:pre>
          <xhtml:p>
            <xhtml:em>To audit the hardening status:</xhtml:em>
            <xhtml:a href="../audit_scripts/Get-EndAuditSystemeventsStatus.ps1">Download Script: Get-EndAuditSystemeventsStatus.ps1</xhtml:a>
          </xhtml:p>
          <xhtml:pre>
            <xhtml:code># Get-EndAuditSystemeventsStatus.ps1
$script:Vulnerable = $false

# Audit Subcategory: Other System Events
$RawOutput = auditpol.exe /get /subcategory:"Other System Events" /r
if ($RawOutput -notmatch ",Other System Events,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security State Change
$RawOutput = auditpol.exe /get /subcategory:"Security State Change" /r
if ($RawOutput -notmatch ",Security State Change,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: Security System Extension
$RawOutput = auditpol.exe /get /subcategory:"Security System Extension" /r
if ($RawOutput -notmatch ",Security System Extension,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

# Audit Subcategory: System Integrity
$RawOutput = auditpol.exe /get /subcategory:"System Integrity" /r
if ($RawOutput -notmatch ",System Integrity,.*,(Success and Failure|Success &amp; Failure)") {
    $script:Vulnerable = $true
}

if ($script:Vulnerable) {
    Write-Output "Non-Compliant"
    exit 1
} else {
    Write-Output "Compliant"
    exit 0
}</xhtml:code>
          </xhtml:pre>
          <xhtml:hr />
        </fixtext>
        <fix system="urn:xccdf:fix:script:powershell"># Configure-EndAuditSystemevents.ps1
Write-Host "Applying Audit Policy category: system-events..." -ForegroundColor Cyan

# Set Audit Subcategory: Other System Events
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Other System Events`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Other System Events to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Other System Events. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security State Change
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security State Change`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security State Change to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security State Change. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: Security System Extension
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"Security System Extension`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory Security System Extension to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory Security System Extension. Exit Code: $($Process.ExitCode)"
}

# Set Audit Subcategory: System Integrity
$Process = Start-Process auditpol -ArgumentList "/set /subcategory:`"System Integrity`" /success:enable /failure:enable" -Wait -NoNewWindow -PassThru
if ($Process.ExitCode -eq 0) {
    Write-Host "    Enforced subcategory System Integrity to Success and Failure" -ForegroundColor Green
} else {
    Write-Error "    Failed to configure subcategory System Integrity. Exit Code: $($Process.ExitCode)"
}</fix>
        <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
          <check-content-ref href="ad-hardening-oval.xml" name="oval:org.adhardening:def:8150" />
        </check>
      </Rule>
    </Group>
  </Group>
</Benchmark>