Hardened
Is this Windows machine hardened? Run one script, drop the file, and see which security settings are missing, in plain English with the fix for each. Covers account policy, user rights, audit policy, and the registry settings that actually matter.
Runs entirely in your browser. Nothing is uploaded, stored, or sent to us.1Collect the machine's configuration
This is the same collector the WorksOnMine uses. Run it from an elevated PowerShell, which matters more here: without elevation the security policy, user rights, and audit policy cannot be read at all, and most of the baseline simply cannot be evaluated. It changes nothing.
2Drop the file here
What this is, and what it is not
This is our own baseline of well-established Windows security settings. It is not a DISA STIG or CIS Benchmark assessment and does not claim conformance with either. Many of these settings also appear in those benchmarks, because they are the same well-known Windows settings, but the rules, thresholds, and wording here are ours.
If you need a real STIG assessment for an audit, use DISA's own SCAP Compliance Checker, which is free and authoritative. This tool is for the much more common case: finding the obvious gaps on a machine quickly, without installing a scanner.
Checking one machine by hand is a useful afternoon.
RFF evaluates every endpoint against a baseline continuously, shows you which ones drifted, and can put them back.
Start free for 100 endpointsWhat gets checked
43 checks across four areas Windows keeps in four different places, which is the main reason
this is tedious to do by hand: the registry, the local security database (via secedit),
user-rights assignment, and the advanced audit policy (via auditpol).
High severity
- NTLMv2 only, LM and NTLMv1 refused. Anything below level 5 leaves the machine willing to speak LM or NTLMv1, both of which are trivially crackable when captured off the wire.
- LM password hashes not stored. A stored LM hash can be brute-forced in minutes regardless of how long the password is.
- WDigest does not cache plaintext credentials. With this enabled, signed-in passwords sit in LSASS in clear text and any credential dumper reads them directly rather than having to crack a hash.
- SMBv1 client driver disabled. SMBv1 is the protocol WannaCry and NotPetya spread over. It has no place on a current network and Windows no longer installs it by default.
- User Account Control enabled. With EnableLUA off, every administrator process runs fully elevated with no prompt and the entire integrity model stops applying.
- Windows Installer does not always install elevated. When enabled, any user can install an MSI as SYSTEM. It is a one-step local privilege escalation and it is checked by every privesc script in existence.
- WinRM does not allow unencrypted traffic. Unencrypted WinRM puts remote management traffic, and anything it carries, on the wire in clear text.
- Only administrators may install printer drivers. This is the PrintNightmare control. With it off, a standard user can load driver code into the spooler, which runs as SYSTEM.
- Microsoft Defender antivirus not disabled by policy. A leftover policy disabling Defender is common on machines that once had a third-party AV, and it can silently leave the machine with no protection at all after that product is removed.
- Act as part of the operating system assigned to nobody. SeTcbPrivilege is the most powerful right in Windows and effectively means full trust by the OS. On a correctly configured machine no account holds it.
Medium severity
- LSA runs as a protected process (RunAsPPL). LSA protection blocks the standard credential-dumping path into LSASS memory. It is the single highest-value setting against lateral movement.
- Anonymous enumeration of SAM accounts blocked. Anonymous SAM enumeration hands an attacker your account list before they have authenticated at all.
- Anonymous enumeration of accounts and shares blocked. The broader form of the same problem, covering share names as well as accounts.
- Anonymous SID/name translation disabled. Allows an unauthenticated caller to map SIDs to names, which is how an attacker finds the real administrator account after it has been renamed.
- SMB server requires signing. Without required signing, SMB sessions can be relayed. NTLM relay to SMB is one of the most reliable moves in any internal assessment.
- SMB client requires signing. The client half of the same protection. Both sides must require it for relay to be genuinely blocked.
- Administrators are prompted for consent. A value of 0 elevates silently without any prompt, which removes the last checkpoint before a malicious installer gains admin.
- Elevation prompts use the secure desktop. Off the secure desktop, another process can draw over or drive the consent dialog.
- Remote UAC token filtering left in place. Setting this to 1 lets local accounts authenticate over the network with a full admin token, which is exactly the condition that makes a shared local admin password catastrophic.
- RDP requires Network Level Authentication. NLA forces authentication before a session is established, which keeps unauthenticated attackers away from the RDP stack itself.
- WinRM does not allow Basic authentication. Basic auth sends credentials in a trivially reversible form and defeats the point of the rest of the WinRM hardening.
- Point and Print still warns before elevating. Setting this to 1 suppresses the elevation prompt on driver install and re-opens PrintNightmare even when the restriction above is set.
- AutoRun disabled on all drive types. 255 disables AutoRun on every drive type, including removable media, which is still a working delivery route for anything physically plugged in.
- PowerShell script block logging enabled. Script block logging records what PowerShell actually executed after de-obfuscation. Without it, an incident investigation of a PowerShell-based attack has almost nothing to read.
- Minimum password length is at least 14. Length is the only property that reliably resists offline cracking once a hash is captured.
- Account lockout threshold is set. A threshold of 0 means accounts never lock, which leaves online password guessing unbounded. This is the most commonly missed setting on standalone machines.
- Guest account disabled. An enabled Guest account is unauthenticated access to whatever it can reach.
- Debug privilege limited to Administrators. SeDebugPrivilege allows reading any process memory, including LSASS. Granting it beyond Administrators is equivalent to granting domain-wide credential access.
- Guests denied network logon. A deny entry holds even if the Guest account is later enabled by accident, which makes it a more durable control than disabling the account alone.
- Guests denied Remote Desktop logon. The same durable deny, applied to the Remote Desktop path.
- Logon events audited for success and failure. Failures show attacks in progress and successes show what the attacker reached. Either half alone leaves an investigation guessing.
- Credential validation audited for success and failure. This is where password spraying against local accounts becomes visible.
- Special logon (privileged) events audited. Records when an account holding sensitive privileges signs in, which is how you spot admin use you did not expect.
- User account management audited. Creating an account is the most common persistence step after a compromise, and without this it leaves no trace.
- Security group management audited. Catches an account being quietly added to the local Administrators group.
- Process creation audited. Process creation events are the backbone of nearly every detection rule worth writing. Without them there is very little to hunt through.
- Audit policy changes are themselves audited. An attacker who turns auditing off should leave one last record doing it.
Low severity
- Cached logon count limited. Each cached logon is a credential verifier retrievable from a stolen machine. Some caching is needed for laptops that travel, so this is a balance rather than zero.
- Password complexity required. Weaker than length on its own, but it does block the single-dictionary-word passwords that get sprayed first.
- Password history prevents reuse. Without history, a forced change can be satisfied by setting the same password straight back.
- Lockout counter reset window is long enough. A short reset window lets an attacker keep guessing indefinitely by simply pausing between attempts.
- Account lockouts audited. A burst of lockouts is often the first visible symptom of a spraying attack.
- Security system extension audited. Records service and driver installation, a standard persistence route.
Honest limits
This finds obvious gaps; it does not replace a scanner. File ACLs and service configuration are not covered, and a rule whose input the collector never read is reported as not checked rather than guessed. Coverage is shown next to the score for exactly that reason.
FAQ
How do I check if a Windows machine is hardened?
Run the collector script from an elevated PowerShell and drop the resulting file on this page. It scores the machine against 43 checks covering account and lockout policy, user-rights assignment, audit policy, and the registry settings that carry the most security weight, and gives you the fix for each gap.
Is this a DISA STIG or CIS Benchmark scan?
No. These are our own rules describing well-established Windows security settings. They are not a copy of any CIS Benchmark or DISA STIG and do not claim conformance with either. If you need a real STIG assessment for an audit, use DISA’s own SCAP Compliance Checker, which is free and authoritative.
Why does it need administrator rights?
Without elevation the collector cannot read security policy, user rights, or audit policy at all, so most of the baseline cannot be evaluated. Note that being signed in as an administrator is not the same as running elevated: with UAC on, a normal PowerShell or ISE window has a filtered token. The tool detects a non-elevated snapshot and says so rather than quietly scoring it.
Does a missing setting count as a failure?
Only when we know the collector actually looked. A rule whose input was never collected is reported as "not checked", never as a pass or a gap. Coverage is shown as prominently as the score, because a hardening report that counts unreadable settings as compliant is worse than no report at all.
Is anything uploaded?
No. The snapshot is scored entirely in your browser. Nothing is uploaded, stored, or sent to us, and the collector is open source so you can read it before running it.
Open source
Hardened is MIT-licensed at github.com/deadarcher/hardened. The rules and the checking engine on this page are byte-identical to the repo copies, and our CI fails the build if they ever drift. Self-host it with one line of Docker:
docker run --rm -p 8080:80 ghcr.io/deadarcher/hardened:latest A check that reads wrong against a modern baseline? Open an issue - rule disagreements are exactly the feedback this wants.