ADSCRIPT-010: UNC Paths to Non-DC Locations
- Plataforma
- Active Directory
- Categoría
- AD Logon Scripts & Network Shares
- Severidad
- High
- Pilar de Zero Trust
- Applications & Workloads (peso 2)
- Fixtures de referencia
- 3
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
The check enumerates every groupPolicyContainer object in the domain and, for each one, reads the four script extensions: HKLM/HKCU Scripts\Logon, Scripts\Logoff, Scripts\Startup, and Scripts\Shutdown, plus the legacy userParameters and scriptPath attribute on every user object. For each script entry it resolves the script path itself (which is usually a local SYSVOL path such as \\<domain>\SYSVOL\<domain>\Policies\{GUID}\Machine\Scripts\Startup\bootstrap.cmd), then opens the script content and parses it for any embedded UNC reference. The regex it uses recognises the full grammar of a Windows UNC path: \\<host>\<share>[\<path>], including hostnames, NetBIOS names, fully qualified DNS names, IPv4 literals, IPv6 literals in the \\ipv6-literal.net form, and DFS namespaces. For every UNC match it resolves the host to a DNS A or AAAA record, compares the resolved name against the set of domain controllers returned by Get-ADDomainController -Filter *, and records non-matches. It also recognises the SYSVOL and NETLOGON shares by name and treats only those two as in-policy when hosted on a DC. For each non-DC UNC target, it then queries the target host for the share ACL (Get-SmbShareAccess), the NTFS ACL on the referenced file (Get-Acl), the SMB signing requirement (Get-SmbServerConfiguration), and the SMB version (SMB1 vs SMBv2/3). Output rows record the GpoName, GpoId, ScriptType (Logon/Logoff/Startup/Shutdown/scriptPath), ScriptPath, UncReferences (list of (host, share, path) tuples), ResolvedHost, HostIsDc (bool), ShareWriteAces, NtfsWriteAces, SmbSigningRequired (bool), SmbProtocol, LinkScope (OUs the GPO is linked to), and AffectedUserOrComputerCount. A row is flagged whenever HostIsDc is false, when ShareWriteAces or NtfsWriteAces include any non-Tier-0 principal, when SmbSigningRequired is false, or when SmbProtocol includes SMB1.
Por qué importa
Logon scripts are one of the highest-trust execution surfaces in Active Directory. They run on every workstation at every interactive logon (or every reboot, in the case of startup scripts), they run in the security context of the user or of SYSTEM, and they run with no user prompt and no SmartScreen interception. Whatever the script reads, includes, or executes inherits that trust. When the script body references a UNC path on a non-DC file server, three concrete risks open up. First, file replacement: any principal with Write on the target file or Modify on the target share can swap in malicious content (a rewritten .cmd, a trojanised .exe, a poisoned PowerShell module) that will execute on every endpoint at the next logon. The blast radius scales with the OU the GPO is linked to: a script on the Default Domain Policy reaches every workstation in the domain. Second, file server compromise: if the file server itself is breached (unpatched OS, weak local admin password, exposed to the internet through a misconfigured firewall rule, recovered from backup without re-keying), the attacker now has a one-shot push to every machine that runs the logon script. The script-server trust relationship turns a Tier 2 file server into a de facto Tier 0 asset without any of the Tier 0 controls. Third, forced authentication and NTLM relay: when a logon script references \\attacker-controlled-host\share, every client that processes the script attempts NTLM authentication to that host. An attacker who can resolve the hostname (DNS hijack, LLMNR/NBT-NS poisoning, ADIDNS record creation, or simply registering a stale hostname) captures NetNTLMv2 hashes from every user and every computer account at every logon, and can relay those hashes to LDAP, ADCS HTTP enrolment, MSSQL, or SMB on other systems. The forced-authentication primitive is the same one MITRE catalogues as T1187, and the relay leg is T1557.001. None of these abuses require any change to the GPO itself, because the policy points outward at content the attacker controls. SpecterOps and Mandiant have both documented logon-script abuse as a recurring foothold and persistence mechanism in real intrusions.
Ruta de ataque
1. Discovery: the attacker, with any domain-authenticated context, enumerates GPOs and their script settings. Get-GPO -All piped through Get-GPOReport -ReportType Xml extracts the Scripts CSE entries. PowerView Get-DomainGPO -Properties displayname,gpcfilesyspath followed by walking \\<domain>\SYSVOL\<domain>\Policies\{GUID}\Machine\Scripts\scripts.ini and User\Scripts\scripts.ini exposes every configured script. The attacker reads every referenced script file and greps for the \\\\ token to find UNC references inside script bodies. 2. Target selection: for each non-DC UNC target the attacker checks share and NTFS ACLs (Get-SmbShareAccess, icacls, Get-Acl) for any principal they can already compromise: Domain Users on a misconfigured share, a service account whose password is exposed elsewhere, a helpdesk group with stale Modify rights, or the local Authenticated Users group on an open share. They also check whether the host responds to DNS at all; an unresolvable hostname is the easiest case, because they can register it themselves. 3. Content replacement (file-write path): with Write access to the referenced file, the attacker rewrites it with their payload. For a .cmd or .ps1 they append a single line that downloads and executes a second-stage; for a .exe or .msi they replace the bytes entirely. No GPO change, no SYSVOL write, no Event ID 5136 on AD. The next logon (or the next 90-minute Group Policy refresh, for startup scripts) pushes the payload to every endpoint in scope. 4. Hostname hijack (DNS path): if the hostname does not resolve, the attacker creates the record. In an AD-integrated DNS zone with the default Authenticated Users CreateChild permission on the zone, any domain user can add an A record for an unused hostname (the ADIDNS abuse documented by Kevin Robertson). They point the record at a host they control and stand up an SMB server with Responder or impacket-smbserver. Every endpoint that runs the logon script now performs NTLM authentication to the attacker-controlled host. 5. NTLM relay (network path): with inbound NTLM, the attacker runs ntlmrelayx or impacket-ntlmrelayx and relays the captured authentication to a high-value target: LDAP on a DC (to add a computer object, set userAccountControl, or write to a Resource Based Constrained Delegation attribute), ADCS HTTP enrolment (ESC8, for a user or machine certificate that lets them request a Kerberos TGT), MSSQL (to xp_cmdshell), or SMB on a host without signing required. Computer accounts authenticating to a startup script give the attacker NetNTLMv2 hashes for every workstation in scope, suitable for relay to other workstations that share local admin credentials. 6. File server compromise (lateral path): if the non-DC file server itself is reachable and unpatched, the attacker compromises it directly (a CVE in SMB, a weak local admin password recovered from LAPS misconfiguration, a service account password in a config file) and replaces the script payload from the inside. The compromise of one mid-tier file server now pushes code to every endpoint that runs the logon script. 7. Persistence: the rewritten payload runs at every logon. The attacker can restore the original file content immediately after the first run to remove the only forensic artifact, then re-plant it on demand. The GPO, the GPO link, and the script entry remain unchanged the entire time.
Cómo lo evalúa Guerrilla
Guerrilla enumerates GPOs with Get-GPO -All and resolves the SYSVOL path for each one via Get-GPO ... | Select-Object -ExpandProperty Path, then walks the \Machine\Scripts and \User\Scripts subtrees of the GPO file system path. For each script extension it reads scripts.ini and psscripts.ini (which list Logon, Logoff, Startup, Shutdown entries with CmdLine and Parameters fields) and resolves CmdLine entries that are themselves UNC paths. It then opens each referenced script file (.cmd, .bat, .ps1, .vbs, .wsh, .py, .lnk metadata) and parses the body for UNC references using a tokeniser that recognises double-backslash followed by a hostname and at least one path segment. It deliberately handles \\ipv6-literal.net forms and DFS namespaces (\\<domain>\<namespace>\...). For every UNC match it: (a) resolves the hostname via Resolve-DnsName -Type A and -Type AAAA; (b) compares the resolved IPs and the hostname (both short and FQDN forms) against (Get-ADDomainController -Filter *).HostName and against the SYSVOL/NETLOGON share names hosted on those DCs; (c) for non-DC targets, calls Get-SmbShareAccess -CimSession <host> -Name <share> to read the share ACL and Get-Acl on the referenced UNC path to read the NTFS ACL; (d) calls Get-SmbServerConfiguration on the target to read RequireSecuritySignature, EnableSMB1Protocol, and EnableSMB2Protocol; (e) walks Get-GPOInheritance on every site, domain, and OU to compute the link scope and the count of users or computers the script reaches. The check also queries every user object for scriptPath (the classic legacy logon script attribute on the user) and resolves it the same way. Output columns: GpoName, GpoId, ScriptType, ScriptPath, UncReferences, ResolvedHost, HostIsDc, NonDcShareWriteAces, NonDcNtfsWriteAces, SmbSigningRequired, SmbProtocol, LinkScope, AffectedCount, Notes. A row is flagged if HostIsDc is false; severity escalates to Critical if the non-DC share or NTFS path is writable by any non-Tier-0 principal or if SMB signing is not required on the target.
Valor recomendado
All script UNC paths reference SYSVOL or NETLOGON on domain controllers; no references to non-DC file shares for script content
Remediación
Scan all scripts for UNC paths (\\server\share patterns). Identify paths that do not point to the domain SYSVOL or NETLOGON shares. Migrate referenced resources to the NETLOGON share where appropriate. For legitimate file share references, ensure the target servers are Tier 0 or Tier 1 assets with appropriate hardening. Document all approved non-DC UNC path dependencies.
Veredictos probados con fixtures
Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.
| Escenario | Veredicto esperado |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- SC-7, AC-3, CM-5
- MITRE ATT&CK
- T1187, T1557, T1059