Tier Zero account's password stored on computers outside Tier Zero

A scheduled task or service on an ordinary server runs as a Tier Zero account and keeps its password there, where any administrator of that server can read it.

Category
Attack Path
Severity
At least High.
Typical owner
the server team that owns the computers, with the owner of the account
Data needed
TaskHound's OpenGraph output, read with its built-in mapping pack, which Pathwarden trusts. Add TaskHound's coverage file so a fix can be confirmed: hosts TaskHound didn't reach stay "Can't tell". See the OpenGraph guide.
On this page

In plain language

A scheduled task set to run "whether the user is logged on or not", or a Windows service that runs as a domain account, needs that account's password, so Windows stores it on the computer. Anyone who is an administrator of that computer can recover it with well-known tools.

When the account is a Domain Admin or another Tier Zero account, every administrator of that server can become a Domain Admin. Unlike a logon session (PW-004), the stored password doesn't go away when someone signs out or the server restarts. The usual fix is a group Managed Service Account (gMSA), whose password Windows manages so nobody has to store it, followed by a new password for the exposed account.

What Pathwarden flags

A scheduled task or Windows service on a computer outside Tier Zero runs as a Tier Zero account (a Domain Admin, a member of another Tier Zero group) and stores that account's password on the computer. Windows keeps a task's password in the computer's credential store and a service's in the LSA secrets; any administrator of the computer (or anyone running as SYSTEM there) can recover it. So every administrator of those computers controls the Tier Zero account.

There is one finding per account, listing every computer and task or service that stores it. The evidence comes from two places, which give the same finding: Pathwarden's built-in collector, which in a Full collection reads the account each service runs as from the computers' registry (ObjectName) and the account each scheduled task stores from its task file on C$ (run-as account and logon type only), both over Kerberos and never the password; and TaskHound (an OpenGraph file, see docs/opengraph.md).

Tasks that store no password (S4U, interactive token) and services that run as a group managed service account, a virtual account (NT SERVICE\...), SYSTEM or a local account are not reported: there is no reusable domain password to take. A disabled service or task still stores its password and is reported. A Tier Zero computer that stores a Tier Zero password is in-tier: not reported, though its path is kept.

Accounts outside Tier Zero whose password a computer stores are not findings, but they are paths: if such an account controls Tier Zero, the path from the computer's administrators shows up in PW-001 and the remediation path.

How attackers use it

Stored credentials are one of the shortest routes from a member server to the domain: local admin on one server, mimikatz or secretsdump for the LSA secrets or the DPAPI-protected task credentials (T1555, Credentials from Password Stores; T1003.004, LSA Secrets), and the attacker signs in as a Domain Admin. Unlike a session, a stored password survives reboots and sign-outs, and nobody has to be logged on.

Find it with Pathwarden

Data needed: TaskHound's OpenGraph output, read with its built-in mapping pack, which Pathwarden trusts. Add TaskHound's coverage file so a fix can be confirmed: hosts TaskHound didn't reach stay "Can't tell". See the OpenGraph guide.

In the web UI or the HTML report, open the Findings tab and expand PW-033: each finding shows who can use it (its exposure), the attack path drawn out, the affected objects, and the fix. The remediation path tells you whether a single plan step closes it. On the command line:

Shell
# every finding of this rule, with its path and fix
pathwarden findings -i .\collect --rule PW-033
# the step-by-step guide on this page, offline
pathwarden guide PW-033
# after the fix: collect again, then check it is gone
pathwarden retest -i .\collect-after --rule PW-033

Exit codes make retest easy to script: 0 Fixed, 1 Still open, 3 Can't tell. See findings lifecycle and retest.

Before you change anything

  • Open each listed task or service and confirm the account it runs as and its logon type (Run whether user is logged on or not with a stored password).
  • Find out what the task or service really needs. A job that runs as a Domain Admin usually needs far less: rights on one share, one database, one OU.
  • Export the task (Export-ScheduledTask) or note the service configuration so you can roll back.

How to fix it

  • Run the task or service as a group managed service account scoped to that computer, with only the rights it needs; or as SYSTEM, or a virtual account, if it needs no network identity of its own.
  • If it truly needs Tier Zero rights, move it to a Tier Zero computer.
  • Then rotate the account's password: every administrator of the computer could already have read it. For a Domain Admin, rotate twice if you also suspect Kerberos tickets were forged with it.

Option B: Make the computer Tier Zero

Only if the computer really belongs there (a Tier Zero management server): add it under Additional Tier Zero in Settings, then fix what PW-003 and PW-004 report about it.

PowerShell

PowerShell
# Tasks that store a password, on one computer
Get-ScheduledTask -CimSession "<Computer>" |
    Where-Object { $_.Principal.LogonType -eq 'Password' } |
    Select-Object TaskPath, TaskName, @{n='RunAs';e={$_.Principal.UserId}}

# Run the task as a gMSA (allowed to retrieve its password on <Computer>)
$p = New-ScheduledTaskPrincipal -UserId "<Domain>\<gMSA>$" -LogonType Password
Set-ScheduledTask -CimSession "<Computer>" -TaskPath "<TaskPath>" -TaskName "<TaskName>" -Principal $p

# Services that run as a domain account
Get-CimInstance Win32_Service -ComputerName "<Computer>" |
    Where-Object { $_.StartName -like '<Domain>\*' } | Select-Object Name, StartName

# Rotate the exposed account's password
Set-ADAccountPassword -Identity "<Account>" -Reset -NewPassword (Read-Host -AsSecureString "New password")

Verify the fix

For services and tasks found by the built-in collector, run a Full collection again, then analyze it. For TaskHound's data, collect again with TaskHound and its coverage file listing the computers you changed (docs/opengraph.md), then analyze the new collection. Either way the finding is marked fixed only when every computer that stored the password was read again in full, for each kind that stored it there; a computer that wasn't reached, or whose services or tasks were read only partly or not at all, keeps it open as "can't tell". A targeted retest can't check it: it re-reads the directory, not the computers.

Roll back

Re-import the exported task (Register-ScheduledTask -Xml (Get-Content task.xml -Raw)) or restore the service account (sc.exe config <Service> obj= <Account>). Do not restore a password that was exposed: set a new one.

References

  1. Microsoft: Group Managed Service Accounts overviewlearn.microsoft.com
  2. TaskHoundgithub.com
  3. Tool Spotlight: TaskHound (r0bit's blog)r0bit.io
  4. MITRE ATT&CK T1555: Credentials from Password Storesattack.mitre.org
  5. MITRE ATT&CK T1003.004: OS Credential Dumping: LSA Secretsattack.mitre.org
  6. MITRE ATT&CK T1078.002: Valid Accounts: Domain Accountsattack.mitre.org

↑↓ to moveEnter to openEsc to close