windowsClient Windows Client Master Checklist
Windows 10/11 workstation hardening — accounts, policy, firewall, services, persistence hunting, and 25 sections deep.
A comprehensive, competition-ready reference for hardening a Windows 7/8/8.1/10/11 client/workstation image in CyberPatriot. Merged and reorganized from "In-Depth Windows Checklist," "The Ultimate Windows Checklist," and an internal hardening script, plus general CyberPatriot community knowledge.
Golden Rule: The README on the Desktop (and any scenario/forensics documents) always overrides generic values in this checklist. If the README says a user must exist, must be an admin, or a service must run — that beats every table below. When in doubt: README > forensics questions > common sense > this document.
Do not blindly run every script/command in this document top to bottom. This is a reference, not a single automated fix-it script. Read the README first, understand what's on the box, then apply the relevant sections. Blind automation can delete a required user, kill a required service, or uninstall required software — all of which cost points.
Table of Contents#
- How to Use This Document
- Initial Recon & README
- Forensics Questions
- User & Group Account Auditing
- Password & Account Lockout Policy
- Local Security Policy — Audit Policy & User Rights Assignment
- Local Security Policy — Security Options
- Windows Firewall
- Malware & Unwanted Software Removal
- Services Hardening
- Startup Programs
- Windows Updates
- User Account Control (UAC)
- Network Shares
- Remote Desktop & Remote Access
- Data Execution Prevention & Exploit Mitigations
- BitLocker & Encryption
- Internet Explorer / Edge / Browser Security
- Power Settings
- Prohibited & Unauthorized Software / Files
- Windows Features (Add/Remove Components)
- Scheduled Tasks
- Registry Autoruns & Hidden Persistence
- Event Log Review & Audit Logging
- Group Policy / secpol.msc / Administrative Templates Reference
- Final Pass / Wrap-Up
0. How to Use This Document#
- Read this whole table of contents once so you know what exists before you start clicking randomly.
- Work as a team — divide sections (accounts, firewall/services, policy, malware/files) so nobody duplicates effort.
- Re-check the scoring report after every few changes. If points drop, undo your last change first — you likely broke something required.
- Keep a scratch notes file (Notepad on the desktop, or paper) listing: required users, required admins, required software, forensics answers, and anything the README calls out as "leave alone."
Tip: Screenshot or write down the starting scoring report state and the README text verbatim before you change anything. If the round disconnects or the VM has to be reset, you don't want to re-derive everything from memory.
1. Initial Recon & README#
- Open the README on the Desktop (or wherever the competition places it) and read the entire thing before touching anything else.
- Note the OS version (
winver, or Settings > System > About) — Windows 7/8/8.1/10/11 behave differently for several steps below. - Identify and write down:
- Authorized/required user accounts (and which ones must be Administrators)
- Users who are explicitly not authorized (candidates for disabling)
- Required installed software / services (don't remove or disable these!)
- Any specific policy values the README overrides (e.g., "minimum password length must be 10" instead of a generic 14)
- The competition's rules about internet access on the scored image (many rounds have no internet access once scoring starts — plan tool usage accordingly)
- Open the scoring report (usually a browser bookmark, tray icon, or desktop shortcut) and note the starting score and any visible categories/vulnerabilities it lists.
- Make a System Restore Point / snapshot now, before hardening, so you have a rollback point if something breaks badly.
# Quick system info dump
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
Get-ComputerInfo | Select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
- Two or three lines of text naming the OS (e.g. "OS Name: Microsoft Windows 10 Pro") and a build number.
Get-ComputerInfoprints a small object withWindowsProductName/WindowsVersionfields filled in.
systeminfocan take 10-20+ seconds to run (it's slow by design, not broken) — wait before assuming it hung.- If
findstrreturns nothing, the OS name string may be localized/different — just run baresysteminfoand read the top of the output. - If
Get-ComputerInfoerrors with "not recognized," you're on an old PowerShell version (pre-5.1, common on Windows 7) — usesysteminfoalone instead, it's older and universally available.
:: Create a manual restore point (requires System Protection enabled - see Section 16-adjacent GUI steps)
wmic.exe /Namespace:\\root\default Path SystemRestore Call CreateRestorePoint "CP Baseline", 100, 7
- Output ending in
ReturnValue = 0;— that's success. - A new restore point appears in
rstrui.exe(System Restore) afterward.
ReturnValuenonzero, or "System Restore is disabled on this drive" — System Protection is off for the C: drive.- Turn it on first:
Control Panel → System → System Protection → Configure → Turn on system protection, then re-run the command. - If
wmicitself says "not recognized" (Windows 11 24H2+ removed it by default), use the GUI instead (sysdm.cpl→ System Protection tab → Create), or fall back to the hypervisor snapshot mentioned just above this section — that's the more reliable safety net anyway and doesn't depend onwmicexisting.
Things to try / extra points#
Tip: Do the Forensics Questions before hardening. Many answers (a suspicious file's timestamp, a specific user's last logon, a weird registry value) can be erased by your own hardening work — e.g., deleting the malicious user before you've recorded their name, or wiping event logs before you've read the entry the question is asking about.
Tip: Take a "before" and "after" screenshot of the scoring report each session — this helps you see exactly which category(ies) changed and reverse-engineer what you fixed vs. broke.
Get-ComputerInfo,Get-HotFix, andGet-Serviceare useful quick first looks that don't change anything on the system yet — safe to run immediately.If the README is a physical printout or a locked/read-only file, you can still grab a digital copy of anything on-disk from PowerShell to paste into your notes without retyping it:
Get-Content "C:\Users\Public\Desktop\README.txt" -ErrorAction SilentlyContinue
Get-ChildItem -Path "$env:USERPROFILE\Desktop","C:\Users\Public\Desktop" -Filter "*.txt","*.rtf","*.docx" -ErrorAction SilentlyContinue
- Empty output with no error usually just means the filename/extension doesn't match (
.docxwon't be caught by a.txtfilter, andFilteronly accepts one pattern at a time in older PowerShell — if the second command shows nothing, try each extension separately:-Filter "*.txt", then-Filter "*.docx"). - If the path itself is wrong, run
Get-ChildItem "$env:USERPROFILE\Desktop"with no filter to see everything that's actually there.
- Check
whoami /allearly — it shows your current username, SID, group memberships, and privileges in one shot, which is useful both for confirming you're logged in as the account you think you are, and as a baseline to compare against later if you suspect your own session got tampered with.
whoami /all
SeDebugPrivilege).- "Access is denied" is unusual for this specific command since it reads your own token — if you see it, your session itself may be broken/restricted; log off and back on.
- If group names show as raw SIDs instead of readable names, the machine can't resolve them locally (harmless, common on isolated/offline images) — the SIDs are still usable for comparison purposes.
Note the current date/time and timezone (
Get-Date, or the clock in the taskbar) against what you'd expect — a wildly wrong system clock can itself be a scored vulnerability and will also make event log timestamps confusing later when you're doing forensics.If your team has more than one person on this box, agree on a simple "claim" system before splitting up sections (e.g., a shared notes doc with initials next to each section) — working the same section twice wastes time, and working conflicting sections simultaneously (e.g., one person disables a service another person just re-enabled) wastes more.
Snapshot Checkpoint — take one right now, before anything else: CyberPatriot images almost always run as a local virtual machine (VirtualBox, VMware, or Hyper-V), and that hypervisor's snapshot feature is your real safety net — separate from, and more powerful than, Windows' own System Restore mentioned above. Take a full snapshot before you change a single setting: VirtualBox = Machine → Take Snapshot; VMware Workstation/Player = VM → Snapshot → Take Snapshot; Hyper-V = right-click the VM in Hyper-V Manager → Checkpoint. If you only take one snapshot all round, make it this one — it can undo a mistake even if Windows itself won't boot or log in anymore.
2. Forensics Questions#
CyberPatriot images frequently include short-answer questions (often as a text file or a form in the README/scoring interface) worth points independent of the scored checklist items. Common categories:
- Identify malware / suspicious files — name of a file, its location, a hash, or which user's profile it lives in.
- Log analysis — "Who logged on at X time?", "What account failed to log in the most?", "When was a specific service installed/started?"
- Hidden/unauthorized user accounts — "How many local user accounts exist?", "Which account should not be here?"
- File permissions / ownership — "Who has access to folder X?", "What permission does user Y have on file Z?"
- System configuration facts — installed OS build, number of CPU cores, installed RAM, disk size, computer name, current IP configuration.
- Policy state facts — "What is the current password policy minimum length?", "Is the firewall currently on?"
- Media/prohibited file identification — "How many mp3 files are on this system?", "What is the name of the pirated software installed?"
Things to try / extra points#
# Who's logged on / logon history without touching anything
query user
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624 or EventID=4625)]]" -MaxEvents 50 |
Select TimeCreated, Id, Message
# List all local accounts and last logon (answers "how many accounts / who logged on last")
Get-LocalUser | Select Name, Enabled, LastLogon
# File count / size questions
Get-ChildItem -Path C:\Users -Recurse -Include *.mp3,*.mp4,*.avi,*.mkv -ErrorAction SilentlyContinue | Measure-Object
# Ownership / permissions on a specific file or folder
icacls "C:\path\to\file_or_folder"
Get-Acl "C:\path\to\file_or_folder" | Format-List
query userlists currently logged-on sessions (username, session name, state).- The
Get-WinEventline prints up to 50 rows of logon/logon-failure events with timestamps — Event ID 4624 = successful logon, 4625 = failed. Get-LocalUserlists every local account with its enabled state and last logon time.- The
Measure-Objectline prints aCount(and if you add-Sumwith-Property Length, a total size). icacls/Get-Aclprint the permission entries (account + rights) on that path.
query usersaying "No User exists..." just means nobody else is logged on right now — not an error.Get-WinEventreturning nothing usually means the Security log's audit policy isn't logging logon events yet (fix that first in Section 5, then re-run) or the log has rolled over past your event — check log size/retention viaGet-WinEvent -ListLog Security.Get-LocalUsershowing blankLastLogonfor an account just means it has genuinely never logged on.Get-ChildItem -Recurseover all ofC:\Userscan take a couple of minutes on a full disk — that's normal, not a hang;-ErrorAction SilentlyContinueis already suppressing the inevitable "access denied" noise from other users' protected folders.icacls/Get-Aclon a path that doesn't exist just errors "cannot find path" — double check the exact path/spelling first withTest-Path.
Tip: If a forensics question asks about something you're about to fix (a malicious user, a bad registry key, a rogue file), answer the question first, or at minimum copy the exact name/path/value into your notes before remediating.
Tip: "Number of administrator accounts," "number of user accounts," and "which services are running" are extremely common forensic-style asks — the commands in Section 3 and Section 9 answer these directly and quickly.
Answer forensics questions using facts you can verify with a command shown above — don't guess. If unsure, re-run the command rather than trusting a earlier note that may now be stale.
- For "which files were recently modified/created" style questions, sort by timestamp instead of scrolling folders by eye:
Get-ChildItem -Path C:\Users -Recurse -File -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 25 FullName, LastWriteTime
C:\Users, newest first.- Takes a while on a full profile — that's expected, not a hang.
- If you only care about one user's files, narrow the
-Pathto that profile folder to speed it up. - An empty result with no error means
C:\Usersitself is unreadable from your account — confirm you're running as Administrator.
- For "what is this file's hash / can you prove it's the same file" style questions, generate a hash rather than eyeballing size/name:
Get-FileHash -Algorithm SHA256 "C:\path\to\file.exe"
Algorithm, Hash (a 64-character hex string for SHA256), and Path.- "Cannot find path" — check the exact path/spelling with
Test-Path "C:\path\to\file.exe"first (tab-completion in the console helps avoid typos). - If you need to match a hash given in MD5 instead of SHA256, add
-Algorithm MD5(or SHA1) — the algorithm must match what the question/answer key used or the hashes will never agree even for identical files.
- For "what did this user open/run recently" style questions, Windows keeps Most-Recently-Used (MRU) lists per user — useful even if the file itself has since been deleted:
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs" -ErrorAction SilentlyContinue
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Recent" -ErrorAction SilentlyContinue | Select Name, LastWriteTime
.lnk) files in the Recent folder with real filenames and timestamps — usually the more readable of the two.HKCUonly shows the currently logged-on user's MRU — to check a different user's history you must load their hive first (reg load HKU\TempHive C:\Users\<user>\NTUSER.DAT, browse underHKU:\TempHive\..., thenreg unload HKU\TempHivewhen done) or log on as that user directly.- An empty Recent folder just means nothing's been opened recently, or the user cleared it — not an error.
- For "how many programs are installed" style questions, count rather than scroll-and-tally in Control Panel:
(Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue | Where-Object DisplayName).Count
- The number looks too low compared to Control Panel's "Programs and Features" — 64-bit Windows keeps a separate 32-bit uninstall key; also check
HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*and add its count, andHKCU:\...\Uninstall\*for per-user installs. - If it returns
0, confirm you didn't typo the registry path — a bad path silently returns nothing rather than erroring.
- For network-configuration questions ("what's this machine's IP/MAC/DNS server"),
ipconfig /allgives everything in one place rather than hunting through several GUI panes:
ipconfig /all
- Adapter shows "Media disconnected" — that NIC has no cable/link, look at the other listed adapters instead.
- If nothing at all is listed, the machine may have all adapters disabled — check
Get-NetAdapter(PowerShell) to see adapter state regardless of connection.
Tip: If a question's answer depends on something you might change later (an IP address, a running process, a registry value), take the habit of writing the exact command output into your notes verbatim rather than paraphrasing — a paraphrase like "it was some Python thing" is much less useful when you go to fill in the answer sheet than a copy-pasted process name and path.
Encoded / Obfuscated Data#
A recurring forensics pattern — a real CyberPatriot practice round included a message on the desktop encoded in base64 — is a text file, filename, or note that isn't in plain English because it's been encoded or lightly "encrypted." Recognize the pattern first, then decode:
| Looks like | Likely encoding | Tell |
|---|---|---|
SGVsbG8gV29ybGQh |
Base64 | Only letters/digits/+//, often padded with = or == at the end, length a multiple of 4 |
48656c6c6f20576f726c6421 |
Hex | Only 0-9 and a-f, always an even number of characters |
01001000 01100101 |
Binary | Only 0s and 1s, usually in 8-character groups |
Uryyb Jbeyq |
ROT13 / Caesar shift | Looks like garbled English but word lengths, spacing, and punctuation all match real text |
Hello%20World%21 |
URL encoding | % followed by two hex digits |
# Base64 decode — works fully offline, no internet needed
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("SGVsbG8gV29ybGQh"))
# Base64 decode from/to a file using certutil (built into every Windows install, no PowerShell needed)
certutil -decode input.b64 output.txt
# Base64 ENCODE (useful if a question asks you to encode an answer, not just decode one)
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("plain text here"))
# Hex decode
-join (("48656c6c6f20576f726c6421") -split '(?<=\G..)(?!$)' | ForEach-Object { [char][Convert]::ToInt32($_,16) })
# ROT13 decode (self-inverse — running it again re-encodes)
function Decode-Rot13($s) {
-join ($s.ToCharArray() | ForEach-Object {
if ($_ -cmatch '[a-z]') { [char]((([int][char]$_ - 97 + 13) % 26) + 97) }
elseif ($_ -cmatch '[A-Z]') { [char]((([int][char]$_ - 65 + 13) % 26) + 65) }
else { $_ }
})
}
Decode-Rot13 "Uryyb Jbeyq"
- Each line prints the decoded/encoded plain text directly to the console (e.g.
"Hello World!"for the base64 example). certutil -decodeprintsCertUtil: -decode command completed successfully.and writesoutput.txtto the current directory.
FromBase64Stringthrowing "Invalid length for a Base-64 char array" means the string isn't valid base64 (wrong data, or you copied it with extra whitespace/line breaks — strip those first:$s -replace '\s','').certutil -decodefailing with a similar complaint has the same cause.- The hex-decode one-liner throws if the string has an odd number of characters or non-hex characters — recheck you copied the whole string.
- If
Decode-Rot13prints gibberish instead of readable English, you're not actually looking at ROT13 (try comparing letter/word patterns against the table above again, or just try ROT13 on it anyway since it's low-cost to test and self-inverse).
- Where to look for encoded content: desktop
.txt/.docxfiles with odd names, a suspiciously long "comment" or "description" field, image file metadata/EXIF (Get-ItemPropertywon't show this — use the file's Properties → Details tab in Explorer), browser bookmarks/saved pages, and recently-modified files (see the timestamp-sort command above). - Steganography (data hidden inside an image) is rarer but does show up — a loose tell is an image file that's unusually large for what it visually shows. Check Properties → Details for hidden metadata first; dedicated stego-detection tools generally aren't pre-installed and may not be available if the round is offline, so don't sink much time here unless a question explicitly points at a specific image.
- If you're not sure which encoding you're looking at, try base64 first — it's by far the most common in practice, and a failed decode attempt is instant feedback that you're looking at something else.
3. User & Group Account Auditing#
GUI Method#
- Open
Start→ typelusrmgr.msc(or viaStart→Run→MMC→File→Add/Remove Snap-in→Local Users and Groupson editions withoutlusrmgr.msc, e.g. Home editions). - Under Users, cross-reference every listed account against the README's authorized list.
- Never delete an account you're unsure about — disable it instead. Deleted local accounts (and their SIDs/profile data) generally cannot be un-deleted.
- Disable any account not listed as authorized (right-click → Disable Account).
- Set/confirm a strong password on every account that should remain enabled.
- Confirm the Guest account is disabled.
- Rename the built-in Administrator account unless you are currently logged on as it — if you rename the account you're using, you may lock yourself out mid-session on some builds. If the README specifically says to leave it named "Administrator," follow the README.
- Under Groups, open Administrators and confirm membership matches exactly what the README authorizes. Remove (don't delete the underlying account — just remove group membership) any unauthorized member from the Administrators group.
- Check other privileged/interesting groups too: Remote Desktop Users, Backup Operators, Power Users.
Command-Line Method (fast triage)#
net user
net user <username>
net localgroup administrators
net localgroup "Remote Desktop Users"
net user(no args) lists all local account names in columns.net user <username>shows that account's full detail (full name, enabled state, password last set, group memberships, etc).net localgroup <name>lists the members of that group.
<username> — re-run bare net user to get exact names/casing. "The group name could not be found" for Remote Desktop Users usually means it genuinely doesn't exist on this SKU (rare) or you mistyped the quotes — group names with spaces need the quotes exactly as shown.Get-LocalUser | Select-Object Name, Enabled, AccountExpires, LastLogon, PasswordRequired, PasswordLastSet
Get-LocalGroupMember -Group "Administrators"
Get-LocalGroupMember -Group "Remote Desktop Users"
wmic useraccount get name,sid,disabled,lockout
wmic table of name/SID/disabled/lockout flags.Get-LocalUser/Get-LocalGroupMembersay "not recognized" on some older Windows 7/8 boxes — these cmdlets need theMicrosoft.PowerShell.LocalAccountsmodule (PowerShell 5.1+); fall back to thenet user/net localgroupcommands above instead, they're older and always available.wmicitself is removed by default starting Windows 11 24H2 — if "not recognized," useGet-CimInstance Win32_UserAccount | Select Name,SID,Disabled,Lockoutas the direct PowerShell equivalent.
:: Disable (do NOT delete) unauthorized default/unknown accounts
net user Guest /active:no
net user DefaultAccount /active:no
net user <unauthorized_user> /active:no
:: Set a strong password for a required user
net user <username> "NewC0mplex!Passw0rd_2026"
:: Rename the built-in Administrator (only if not currently using it / README allows)
wmic useraccount where name='Administrator' call rename name='RenamedAdmin'
net user ... /active:no prints "The command completed successfully." Re-run net user <name> afterward and confirm "Account active" now says No. The password-set command prints the same success line; the rename command's success shows as ReturnValue = 0; in its output block.- "Access is denied" on any of these means your shell isn't elevated — right-click Command Prompt/PowerShell → Run as administrator and retry. "System error 2224 has occurred.
- The password does not meet the password policy requirements" means your chosen password fails the complexity/length policy you (or the README) set — pick a longer password mixing case, digits, and symbols.
- Don't disable an account you're not certain is unauthorized — cross-check the README's list again first.
# Same rename via PowerShell/WMI object
(Get-WmiObject -Class Win32_UserAccount -Filter "Name='Administrator'").Rename("RenamedAdmin")
# Remove a user from Administrators without touching the account itself
Remove-LocalGroupMember -Group "Administrators" -Member "SuspiciousUser"
net user RenamedAdmin and Get-LocalGroupMember -Group Administrators afterward.Get-WmiObjectis deprecated/removed in PowerShell 7+ ("not recognized") — use thewmicornet userrename method above instead on newer systems, orGet-CimInstanceas the modern replacement.Remove-LocalGroupMembererroring "member does not exist in this group" just means that account wasn't actually in Administrators — double-check membership first withGet-LocalGroupMember -Group Administratorsrather than assuming the removal command's phrasing is wrong.
Things to try / extra points#
Tip:
net userandGet-LocalUsersometimes disagree with what Control Panel shows for accounts hidden from the welcome/login screen via the registrySpecialAccounts\UserListkey. Always trust the command-line/registry truth over the GUI login screen.
# Reveal accounts hidden from the Windows logon screen
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" -ErrorAction SilentlyContinue
- Check
net accountsto see the currently active password/lockout policy in one shot — useful both for forensics questions and for verifying your policy changes actually applied:
net accounts
- Compare
Get-LocalUseroutput against the SAM registry hive count if you suspect an account is being hidden from normal enumeration (rare, but seen in harder images):
Get-ChildItem "HKLM:\SAM\SAM\Domains\Account\Users\Names" -ErrorAction SilentlyContinue
This key is normally locked down to SYSTEM; if you can't read it as Administrator, that itself can be a forensics-question answer ("why can't you view this key").
Double- and triple-check before deleting: if you truly must recreate a required user because it was wrongly deleted, use
net user <name> <password> /addand re-add to the correct groups — but understand the new SID means file ownership/permissions tied to the old account are gone. Prevention (disable, don't delete) is far better than recovery.Check for accounts where the password is set to never expire — a common lingering-access trick, especially on an account that also has no lockout/complexity applied to it:
Get-LocalUser | Select Name, Enabled, PasswordExpires, PasswordLastSet
Get-CimInstance Win32_UserAccount | Where-Object { $_.PasswordExpires -eq $false } | Select Name, Disabled
- List every local group, not just Administrators — a vulnerable image can plant an unauthorized account in a less-obvious group (Backup Operators and Power Users both carry real privileges most competitors forget to check):
Get-LocalGroup
net localgroup
foreach ($g in (Get-LocalGroup).Name) { Write-Host "`n== $g ==" ; Get-LocalGroupMember -Group $g -ErrorAction SilentlyContinue }
On Windows 10/11,
netplwiz(Start → Run →netplwiz) is a faster GUI alternative tolusrmgr.mscfor a quick pass on account list + group membership + "require password to log on," if the full Local Users and Groups snap-in feels slow to navigate.Verify a rename or password change actually stuck by reading it back immediately rather than assuming the dialog box succeeding means it worked:
Get-LocalUser | Select Name, Enabled, PasswordLastSet
Snapshot Checkpoint: You're about to start mass-editing Local Security Policy (Sections 4–6) using
secpol.mscandseceditimport/export. A badseceditimport or an overly aggressive lockout/rights change can lock accounts out or break logon entirely, and it's not always obvious which line caused it. Take a fresh snapshot now if you don't already have one from the last few minutes — it's much faster than troubleshooting a locked-out box afterward.
4. Password & Account Lockout Policy#
Configure via secpol.msc → Account Policies → Password Policy / Account Lockout Policy, or via net accounts, or via secedit export/import for scripted changes.
| Setting | Suggested Value* |
|---|---|
| Enforce Password History | 24 (source table used 8; many CyberPatriot guides recommend higher, e.g. 24) |
| Maximum Password Age | 30 days (or per README; do not set to 0/never) |
| Minimum Password Age | 1 day |
| Minimum Password Length | 8–14 characters (higher is generally safer; follow README if specified) |
| Password Must Meet Complexity Requirements | Enabled |
| Store Passwords Using Reversible Encryption | Disabled |
| Account Lockout Duration | 15–30 minutes |
| Account Lockout Threshold | 3–5 invalid attempts |
| Reset Account Lockout Counter After | 10–15 minutes |
*Two sources disagreed slightly on exact numbers (e.g., 8 vs. 24 for history, 7 vs. 5 for lockout threshold). There is no single "official" CyberPatriot number — use reasonable, defensible values in this range unless the README specifies exact numbers, in which case follow the README exactly.
GUI Method#
-
secpol.msc→ Security Settings → Account Policies → Password Policy — set each value above. - Account Policies → Account Lockout Policy — set each value above.
Command-Line / Scripted Method#
- Step 1 — check current policy. This is read-only and safe to run any time:
net accounts
The secedit export/edit/import pattern below does the same job as the GUI method above, but scripted — useful if you're applying the same values across multiple machines, or just prefer text-editing to clicking through dialogs. It's four distinct steps; don't skip the "verify" step at the end.
- Step 2 — export the current policy to a text file. This creates
C:\secpol.cfg, a plain-text snapshot of every current Local Security Policy setting:
secedit /export /cfg C:\secpol.cfg
The task has completed successfully. and C:\secpol.cfg now exists (confirm with dir C:\secpol.cfg).C:\ — some lockdown images restrict writing to the drive root; export to C:\Users\Public\secpol.cfg instead (adjust every later step's path to match). "The task has completed with one or more errors" alongside a mostly-fine-looking file is usually still safe to proceed with — open the file and confirm the [System Access] section is present and readable before continuing.- Step 3 — edit the exported file. Open
C:\secpol.cfgin Notepad, find the[System Access]section, and change (or add, if missing) these specific lines to the values below — leave every other line in the file untouched:
MinimumPasswordAge = 1
MaximumPasswordAge = 30
MinimumPasswordLength = 14
PasswordComplexity = 1
PasswordHistorySize = 24
LockoutBadCount = 5
ResetLockoutCount = 15
LockoutDuration = 30
RequireLogonToChangePassword = 1
Save the file when done.
Expected result: Notepad saves without complaint; the file still opens and looks like normal .ini-style text.
If it fails: If Notepad refuses to save citing "Access is denied," you edited a copy outside your own write permissions (e.g. C:\ root with a restrictive image) — save as a copy to C:\Users\Public\ instead and use that path in Step 4. If a line you need (e.g. PasswordHistorySize) simply doesn't exist in the exported file, add it as a new line under [System Access] exactly as shown — secedit accepts added lines as long as they're valid keys in the right section.
- Step 4 — re-import the edited file to apply it. This is the step that actually changes the running system's policy:
secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.cfg /areas SECURITYPOLICY
The task has completed successfully. A log is written to %windir%\security\logs\scesrv.log if you need to double check details.- "The task has completed with one or more errors" here (unlike the export step) usually DOES mean a line in your edited
.cfgis malformed — openscesrv.log(path above) and look for the specific line/key it choked on; a common cause is a typo'd key name or a value outside the valid range (e.g.MinimumPasswordLength = 30— max is 14 on most builds). - Fix the offending line in
secpol.cfgand re-run this command; it's safe to re-run.
- Step 5 — verify it took effect. Re-run
net accountsand confirm the numbers match what you just set —seceditfails silently on a malformed line, so this step isn't optional:
net accounts
secpol.cfg (e.g. minimum password length shows 14, not the old default)./db path you configured against isn't the one actually governing local policy (rare — stick to the exact path shown), or a domain GPO is overriding your local setting (see the gpresult /r tip further down this section) — a domain-joined machine's local policy can be silently beaten by Group Policy, and no error will tell you that's happening.Prefer to skip manual Notepad editing? The block below automates Steps 2–4 as one script — same net effect, no Notepad required:
secedit /export /cfg C:\secpol.cfg
(Get-Content C:\secpol.cfg) | ForEach-Object {
if ($_ -match "MinimumPasswordAge") { "MinimumPasswordAge = 1" }
elseif ($_ -match "MaximumPasswordAge") { "MaximumPasswordAge = 30" }
elseif ($_ -match "MinimumPasswordLength") { "MinimumPasswordLength = 14" }
elseif ($_ -match "PasswordComplexity") { "PasswordComplexity = 1" }
elseif ($_ -match "PasswordHistorySize") { "PasswordHistorySize = 24" }
elseif ($_ -match "LockoutBadCount") { "LockoutBadCount = 5" }
elseif ($_ -match "ResetLockoutCount") { "ResetLockoutCount = 15" }
elseif ($_ -match "LockoutDuration") { "LockoutDuration = 30" }
elseif ($_ -match "RequireLogonToChangePassword") { "RequireLogonToChangePassword = 1" }
else { $_ }
} | Set-Content C:\secpol.cfg
secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.cfg /areas SECURITYPOLICY
net accounts
net accounts at the end prints the new values.- If none of the
-matchconditions fire (values in the file look untouched), the exported.cfgmay use different casing or spacing than the-matchpatterns expect on this Windows build — openC:\secpol.cfgin Notepad first to confirm the exact key names, and adjust the-matchstrings to match exactly if needed. Set-Contentfailing with "Access is denied" has the same fix as the manual Step 3 note above — redirect the working copy toC:\Users\Public\.
Things to try / extra points#
Tip: Password Policy and Account Lockout Policy are among the most reliably scored, highest-yield items in CyberPatriot — they're simple checkboxes/numbers for the engine to verify and are almost always tested. Do this section early and don't skip it.
Tip: After using
secedit, immediately re-runnet accountsto confirm the values actually took —seceditimport syntax errors fail silently in some Windows builds.
- "Limit local account use of blank passwords to console logon only" should be Enabled — check under Security Options (Section 6).
- If a user has no password and can't have one set for scenario reasons, that specific policy interaction is a classic trap — verify with
net user <name>thatPassword RequiredisYes.
CIS Benchmark cross-reference: The value ranges in the table above align closely with the CIS Microsoft Windows 10/11 Benchmark, Level 1 guidance for Account Policies — the published CIS baseline uses the same shape (password history in the 20s, minimum length around 14 characters, complexity enabled, lockout threshold in the low single digits). If you have access to the free CIS Benchmark PDF (published by the Center for Internet Security), it's a legitimate, citable source if a judge or mentor asks where a specific number came from, rather than "a checklist said so."
CIS Level 1 also calls out "Store passwords using reversible encryption" (must be Disabled — already reflected in the table above) as a setting worth double-checking specifically; it's easy to overlook because it defaults correctly on most images, but a vulnerable image may have flipped it.
If
secpol.mscwon't open or its Account Policies node looks empty/greyed-out (seen occasionally on Home editions or oddly-configured images), fall back to thenet accountscommand-line method above — it reads and can partially set the same underlying policy without the snap-in.Double-check the policy actually applies locally and isn't being silently overridden by a domain GPO if this machine is domain-joined —
gpresult /r(or the fuller/zdump discussed in Section 24) will show whether "Local Group Policy" or a domain policy actually won for each setting.Each individual user account also has its own per-account password flags that override the domain-wide/local policy for that one account — worth a quick sanity check if one specific account seems immune to your policy changes:
Get-CimInstance Win32_UserAccount | Select Name, PasswordRequired, PasswordChangeable, PasswordExpires
-Filter "LocalAccount=True" to restrict to local accounts only and speed it up.5. Local Security Policy — Audit Policy & User Rights Assignment#
Audit Policy (secpol.msc → Local Policies → Audit Policy)#
- Set every audit category to Success and Failure unless the README says otherwise. This is explicitly called out in the source checklist as a category worth extra attention.
:: Enable auditing on every legacy category, success+failure
auditpol /set /category:"Account Logon" /success:enable /failure:enable
auditpol /set /category:"Account Management" /success:enable /failure:enable
auditpol /set /category:"Detailed Tracking" /success:enable /failure:enable
auditpol /set /category:"DS Access" /success:enable /failure:enable
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
auditpol /set /category:"Object Access" /success:enable /failure:enable
auditpol /set /category:"Policy Change" /success:enable /failure:enable
auditpol /set /category:"Privilege Use" /success:enable /failure:enable
auditpol /set /category:"System" /success:enable /failure:enable
:: Or, blanket enable everything at once
auditpol /set /category:* /success:enable /failure:enable
The command was successfully executed.auditpol /list /category:* first to get the exact names this build recognizes, and use those verbatim instead of retyping from memory. "Access is denied" means the shell isn't elevated — re-open as Administrator.# Review current audit policy state
auditpol /get /category:*
No Auditing, Success, Failure, or Success and Failure.auditpol /get /category:* > C:\audit_state.txt) and open that in Notepad rather than scrolling a truncated console buffer.User Rights Assignment#
Recommended baseline (adjust to README; the general rule is: sensitive rights go to Administrators only, and dangerous rights should be assigned to No One unless specifically required):
| User Right | Recommended Assignment |
|---|---|
| Access Credential Manager as a trusted caller | Administrators |
| Access this computer from the network | (No unauthorized accounts; keep Administrators/authenticated users only as required) |
| Act as part of the operating system | No One |
| Add workstations to domain | No One |
| Adjust memory quotas for a process | No One (or SYSTEM/service accounts only) |
| Allow log on locally | Administrators (+ authorized standard users per README) |
| Allow log on through Remote Desktop Services | No One (unless RDP required) |
| Back up files and directories | Administrators |
| Bypass traverse checking | No One (leave default groups like LOCAL SERVICE/NETWORK SERVICE alone) |
| Change the system time | No One (or Administrators only) |
| Change the time zone | No One (or Administrators only) |
| Create a pagefile | No One |
| Create a token object | Administrators (rarely assigned at all) |
| Create global objects | Administrators |
| Create permanent shared objects | No One |
| Create symbolic links | Administrators |
| Debug programs | No One |
| Deny access to this computer from the network | No One (empty unless blocking a specific bad account) |
| Deny log on as a batch job | No One |
| Deny log on as a service | No One |
| Deny log on locally | No One |
| Deny log on through Remote Desktop Services | No One |
| Enable computer and user accounts to be trusted for delegation | Administrators |
| Force shutdown from a remote system | No One |
| Generate security audits | No One |
| Impersonate a client after authentication | No One (leave built-in service accounts alone) |
| Increase a process working set | No One |
| Increase scheduling priority | Administrators |
| Load and unload device drivers | Administrators |
| Lock pages in memory | Administrators |
| Log on as a batch job | No One |
| Log on as a service | No One |
| Manage auditing and security log | Administrators |
| Modify an object label | Administrators |
| Modify firmware environment values | Administrators |
| Perform volume maintenance tasks | Administrators |
| Profile single process | Administrators |
| Profile system performance | Administrators |
| Remove computer from docking station | Administrators |
| Replace a process level token | Administrators |
| Restore files and directories | Administrators |
| Shut down the system | Administrators |
| Synchronize directory service data | Administrators |
| Take ownership of files or other objects | Administrators |
Do not remove built-in
NETWORK SERVICE/LOCAL SERVICEfrom rights they hold by default, even if the field appears to show "No One" as your target value — that guidance applies to user accounts, not the built-in service identities. Removing those breaks core OS functionality.
Command-Line Method#
:: Export the current user-rights assignment for review or forensic-question answers
secedit /export /cfg C:\rights.txt /areas USER_RIGHTS
The task has completed successfully. and creates C:\rights.txt — a plain-text INF-style file with a [Privilege Rights] section listing each Se*Right/Se*Privilege and the SIDs assigned to it (e.g. SeDebugPrivilege = *S-1-5-32-544 for Administrators).- "Access is denied" means the prompt isn't elevated — reopen cmd/PowerShell as Administrator.
- If the file already exists and looks stale, delete it first or change the output path;
secedit /exportsilently overwrites, so a stale file is usually a sign you ran it before a change took effect rather than a real error.
Select-String -Path C:\rights.txt -Pattern "SeDebugPrivilege","SeTakeOwnershipPrivilege","SeRemoteInteractiveLogonRight","SeNetworkLogonRight"
- One matching line per right that's actually assigned to someone, in the form
SeDebugPrivilege = *S-1-5-32-544(SIDs, not names — S-1-5-32-544 is the well-known SID for Administrators). - A right with no one assigned won't appear at all.
- No output at all means either the right has zero assignees (fine, that's "No One") or
C:\rights.txtdoesn't exist yet — run thesecedit /exportcommand above first. - To translate an unfamiliar SID to a username, use
wmic useraccount where sid='S-1-5-...' get nameorGet-CimInstance Win32_UserAccount -Filter "SID='S-1-5-...'".
Things to try / extra points#
Tip (high yield): Watch for
SeRemoteInteractiveLogonRight(Allow log on through RDS) andSeDenyRemoteInteractiveLogonRight— these directly gate who can RDP in, and vulnerable images commonly add an unauthorized account here.
Tip:
SeDebugPrivilegeandSeTakeOwnershipPrivilegegranted to a non-admin standard user is a classic privilege-escalation plant — check these first if a forensics question mentions "elevated privileges" or "unusual access."
CIS Benchmark cross-reference: CIS's Advanced Audit Policy Configuration guidance (a more granular replacement for the legacy 9-category Audit Policy used above) recommends specific Success/Failure settings per subcategory rather than one blanket "enable everything" — some subcategories are recommended Failure-only specifically to cut down on log noise. The blanket
auditpol /set /category:* /success:enable /failure:enablecommand in this section is a reasonable, safe superset for a competition round, but if you have time, openingsecpol.msc → Advanced Audit Policy Configurationand reviewing the roughly 50 individual subcategories against the CIS per-subcategory table is a legitimate "extra credit" pass.
CIS Level 1 User Rights Assignment guidance also explicitly calls out adding Guest to the "Deny access to this computer from the network," "Deny log on as a batch job," "Deny log on as a service," and "Deny log on locally" rights (not just leaving them at "No One") — an enabled Guest account with logon rights left unrestricted is a classic combination vulnerability. Cross-check this if your image has the Guest account enabled for any reason.
Audit MPSSVC Rule-Level Policy Change — a CIS Level 1 Advanced Audit Policy subcategory that's easy to overlook because it's not one of the "big" categories, but it specifically logs changes to Windows Firewall rules (
MPSSVCis the firewall service). Since firewall tampering is one of the most common things a scenario plants, having this enabled means you get a log trail if a rule gets silently added/removed after your initial pass:cmdauditpol /set /subcategory:"MPSSVC Rule-Level Policy Change" /success:enable /failure:enableExpected result:The command was successfully executed.If it fails:"The subcategory name is unrecognized" — the exact wording is version-sensitive; runauditpol /list /subcategory:"Policy Change"to see the exact subcategory names this build recognizes and copy the spelling verbatim (quotes and all).auditpol /get /category:*is hard to read as a wall of console text — add/rfor CSV-formatted output, which pastes cleanly into a spreadsheet or notes doc if you want to review all ~50 subcategories at once:
auditpol /get /category:* /r
Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting) followed by one row per subcategory — pastes cleanly into Excel/Sheets via copy-paste or auditpol /get /category:* /r > C:\audit.csv then opening the CSV./r version in a narrow console window — that's just word-wrap, not a real failure; redirect to a file and open it in Notepad/Excel to see the true CSV structure. "Access is denied" means the shell isn't elevated.- Back up your audit policy configuration once you've got it the way you want, so a later mistake (or a teammate accidentally re-running an old command) doesn't quietly undo your work:
auditpol /backup /file:C:\auditpolicy_backup.csv
:: To restore later if needed:
auditpol /restore /file:C:\auditpolicy_backup.csv
/backupprintsThe command was successfully executed.and creates the CSV file (despite the name, it's actually a full binary-safe audit policy dump, not a simple readable CSV — don't try to hand-edit it)./restorere-applies whatever state was captured, also printing success.
- "Access is denied" needs an elevated prompt.
- If
/restoreseems to do nothing, verify you're restoring the right file and that it was actually written by/backupon this same OS version — an audit policy backup isn't reliably portable between different Windows builds.
- If you'd rather review Audit Policy visually instead of parsing command output,
secpol.msc → Security Settings → Advanced Audit Policy Configuration → System Audit Policiesshows every subcategory with checkboxes for Success/Failure — a good option when double-checking a specific category rather than dumping everything.
6. Local Security Policy — Security Options#
secpol.msc → Local Policies → Security Options.
| Setting | Recommended Value |
|---|---|
| Accounts: Administrator account status | Enabled only if you are using it (per README); otherwise leave as configured by README |
| Accounts: Guest account status | Disabled |
| Accounts: Limit local account use of blank passwords to console logon only | Enabled |
| Accounts: Rename administrator account | Rename it (unless currently logged on as it / README says not to) |
| Accounts: Rename guest account | Rename it |
| Audit: Audit the access of global system objects | Enabled |
| Audit: Audit the use of Backup and Restore privilege | Enabled |
| Audit: Force audit policy subcategory settings... | Enabled |
| Audit: Shut down system immediately if unable to log security audits | Disabled |
| Devices: Allow undock without having to log on | Disabled |
| Devices: Allowed to format and eject removable media | Administrators |
| Devices: Prevent users from installing printer drivers | Enabled |
| Devices: Restrict CD-ROM access to locally logged-on user only | Enabled |
| Devices: Restrict floppy access to locally logged-on user only | Enabled |
| Domain member: Digitally encrypt or sign secure channel data (always) | Enabled |
| Domain member: Disable machine account password changes | Disabled (leave changes allowed) |
| Domain member: Maximum machine account password age | 30 days (or 13-day style hardened value if scenario calls for it) |
| Domain member: Require strong (Windows 2000 or later) session key | Enabled |
| Interactive logon: Display user information when session is locked | Do not display user information |
| Interactive logon: Do not display last user name | Enabled |
| Interactive logon: Do not require CTRL+ALT+DEL | Disabled |
| Interactive logon: Message text/title for users attempting to log on | Leave blank unless README specifies a banner |
| Interactive logon: Number of previous logons to cache | 0 (or 1–2 if offline domain logon is required) |
| Interactive logon: Prompt user to change password before expiration | 5–14 days |
| Interactive logon: Require smart card | Disabled (unless scenario requires) |
| Interactive logon: Smart card removal behavior | Lock Workstation / No Action per scenario |
| Microsoft network client: Digitally sign communications (always) | Enabled (or Disabled if it breaks required functionality — verify) |
| Microsoft network client: Send unencrypted password to third-party SMB servers | Disabled |
| Microsoft network server: Amount of idle time required before suspending session | 15–45 minutes |
| Microsoft network server: Digitally sign communications (always) | Enabled |
| Microsoft network server: Disconnect clients when logon hours expire | Enabled |
| Network access: Allow anonymous SID/Name translation | Disabled |
| Network access: Do not allow anonymous enumeration of SAM accounts | Enabled |
| Network access: Do not allow anonymous enumeration of SAM accounts and shares | Enabled |
| Network access: Do not allow storage of passwords/credentials for network auth | Enabled |
| Network access: Let Everyone permissions apply to anonymous users | Disabled |
| Network access: Named pipes that can be accessed anonymously | Clear/empty |
| Network access: Remotely accessible registry paths (and paths and sub-paths) | Remove all/unnecessary entries |
| Network access: Restrict anonymous access to Named Pipes and Shares | Enabled |
| Network access: Shares that can be accessed anonymously | Clear/empty |
| Network access: Sharing and security model for local accounts | Classic |
| Network security: Allow Local System to use computer identity for NTLM | Disabled (per scenario) |
| Network security: Do not store LAN Manager hash value on next password change | Enabled |
| Network security: LAN Manager authentication level | Send NTLMv2 response only, refuse LM & NTLM |
| Network security: LDAP client signing requirements | Require signing |
| Shutdown: Allow system to be shut down without having to log on | Disabled |
| System objects: Require case insensitivity for non-Windows subsystems | Enabled |
| User Account Control: Admin Approval Mode for the Built-in Administrator account | Enabled |
| User Account Control: Behavior of the elevation prompt for administrators | Prompt for consent on the secure desktop |
| User Account Control: Behavior of the elevation prompt for standard users | Prompt for credentials on the secure desktop |
| User Account Control: Detect application installations and prompt for elevation | Enabled |
| User Account Control: Only elevate UIAccess applications installed in secure locations | Enabled |
| User Account Control: Run all administrators in Admin Approval Mode | Enabled |
| User Account Control: Switch to the secure desktop when prompting for elevation | Enabled |
| User Account Control: Virtualize file and registry write failures to per-user locations | Enabled |
If a listed policy isn't present on your specific image (varies by SKU/edition), skip it — use judgment.
Things to try / extra points#
Tip (high yield):
Network access: Do not allow anonymous enumeration of SAM accounts (and shares)andLAN Manager authentication levelare frequently included in scored checklists because they map directly to well-known enumeration/relay attacks — prioritize these.
Tip: Many of these Security Options can also be read/set via the registry directly if
secpol.mscis being uncooperative (e.g., missing snap-in on Home editions) — searchHKLM:\SYSTEM\CurrentControlSet\Control\Lsafor LAN Manager/anonymous-access values, andHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Systemfor UAC/logon values.
# Restrict anonymous access / null sessions
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictAnonymous" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictAnonymousSAM" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "EveryoneIncludesAnonymous" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "RestrictNullSessAccess" -Value 1 -Type DWord
- No output on success (PowerShell's
Set-ItemPropertyis silent by default). - Verify with
Get-ItemProperty <path> -Name <name>afterward to confirm the value stuck.
Lsa/LanmanServer\Parameters, both are core keys present since XP). "Requested registry access is not allowed" means the shell isn't elevated — reopen PowerShell as Administrator.CIS Benchmark cross-reference: This entire Security Options table (accounts, audit, devices, interactive logon, network access/security, UAC) is essentially a client-focused subset of CIS Microsoft Windows 10/11 Benchmark, Level 1, "Security Options." If you want to verify a value against an authoritative published source rather than this document, that's the section to open.
CIS Level 1 also recommends "Network security: Minimum session security for NTLM SSP based (including secure RPC) clients" and the matching "...servers" setting both be set to Require NTLMv2 session security, Require 128-bit encryption — a natural companion to the LAN Manager authentication level setting already in the table above.
Level 2 (worth trying if you have time and it doesn't break required functionality): CIS Level 2 recommends "Network access: Restrict clients allowed to make remote calls to SAM" be limited to Administrators. This is stricter than Level 1 and can break legitimate remote-administration tooling if your scenario relies on any — test carefully before depending on it for points.
secedit /export /cfg C:\secopts.cfg /areas SECURITYPOLICYdumps every Security Options value as plain text in one shot — much faster to skim (or grep withSelect-String) than clicking through ~50 individual dialog boxes insecpol.mscone at a time when you just want to verify current state.gpresult /zdumps the full effective policy actually applied to this machine and user — every Computer and User Configuration setting currently in force, from whatever combination of local policy, any GPOs, and any registry-level tampering produced it. Run it as a final verification pass after you've made your changes:powershellgpresult /z > C:\gpresult_after.txtExpected result:Creates a large text file (often several thousand lines) withCOMPUTER SETTINGSandUSER SETTINGSsections, each listing the winning GPO/local policy source and every applied setting value.If it fails:- "Access is denied" needs elevation.
- If the file seems suspiciously short or missing whole sections, the account you're running it as may lack rights to read some policy data — run from an elevated Administrator prompt, not just any admin-group console.
gpresult /zcan take 10-30+ seconds on domain-joined machines; it isn't hung, just slow. This is useful two ways: (1) it confirms your own hardening actually took effect (rather than trusting that clicking "Apply" insecpol.mscworked), and (2) it can surface policy-based sabotage you haven't found yet — a setting showing up in the effective result that you never configured and that isn't in this checklist is worth investigating.
"Network security: LAN Manager authentication level" has a direct registry equivalent if you'd rather script it than click through the dropdown — the value
5corresponds to "Send NTLMv2 response only, refuse LM & NTLM" (the recommended setting in the table above):
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LmCompatibilityLevel" -Value 5 -Type DWord
- No output on success.
- Confirm with
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LmCompatibilityLevelwhich should return5.
Get-ItemProperty on a fresh image is normal — Set-ItemProperty creates the value if missing, so run the Set first. "Requested registry access is not allowed" means the console isn't elevated.- "Network access: Do not allow anonymous enumeration of SAM accounts (and shares)" corresponds to
RestrictAnonymousat the registry level:0= allow (bad, vulnerable default on some old images),1= don't allow enumeration of SAM accounts,2= don't allow enumeration of SAM accounts and shares (strictest, matches "and shares" in the policy name). Cross-check the live value if thesecpol.mscGUI setting doesn't seem to be sticking:
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictAnonymous" -ErrorAction SilentlyContinue
- A property listing including
RestrictAnonymous : 1(or2for the strictest "and shares" setting). - Matches whatever you set via
secpol.mscor the earlierSet-ItemPropertycommand.
- No
RestrictAnonymousline in the output means the value has never been explicitly set (defaults apply, which vary by OS version) — that's why-ErrorAction SilentlyContinueis there, so it doesn't throw red error text for a missing value. - Set it explicitly with
Set-ItemProperty ... -Value 1 -Type DWordrather than assuming the default is safe.
7. Windows Firewall#
GUI Method#
- Open
wf.msc(Windows Firewall with Advanced Security) directly, or via MMC → Add/Remove Snap-ins → Windows Firewall with Advanced Security. - On the home page, click Windows Firewall Properties. This one dialog has three tabs — Domain Profile, Private Profile, Public Profile — and you need to repeat the same four checks on each of the three tabs (Windows applies a different firewall configuration depending on which network type you're connected to, so all three need to be correct, not just the one currently active):
- Firewall state dropdown: On. (This is the master switch for that profile — everything else is irrelevant if this is off.)
- Inbound connections: Block (the default). (This is what actually stops unsolicited incoming traffic.)
- Outbound connections: Allow (the default, unless README says otherwise). (Blocking outbound by default tends to break required functionality unless the scenario specifically calls for it — don't flip this without a reason.)
- Click the Settings button (if reviewing notification behavior) and the Logging section's Customize button: set Log dropped packets = Yes, Log successful connections = Yes, and raise the log size limit (e.g., 4096–16384 KB). (This is what gives you evidence later if a forensics question asks about blocked/allowed connections.)
- Click OK to close the Properties dialog once all three tabs are done.
- Back on the main window, click Inbound Rules in the left pane and scan the list for anything related to: Telnet, netcat/nc/Ncat, File and Printer Sharing (unless required), Remote Assistance, Remote Desktop (unless required), SNMP, SMTP, or any other rule that shouldn't be allowing traffic in. Disable (don't delete) anything unauthorized you find.
- Click Outbound Rules and repeat the same review if the scenario calls for outbound restriction — this is less commonly needed than inbound review, but worth a glance.
Command-Line Method#
netsh advfirewall set allprofiles state on
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound
netsh advfirewall set allprofiles logging droppedconnections enable
netsh advfirewall set allprofiles logging allowedconnections enable
Ok.blockinbound,allowoutbound must be comma-separated with no space); retype carefully rather than reusing a hand-edited copy.Get-NetFirewallProfile | Select Name, Enabled, DefaultInboundAction, DefaultOutboundAction
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True -DefaultInboundAction Block -DefaultOutboundAction Allow
# Review all enabled inbound rules for anything suspicious
Get-NetFirewallRule -Direction Inbound -Enabled True | Select DisplayName, Action, Profile
# Disable a specific suspicious rule
Disable-NetFirewallRule -DisplayName "Some Suspicious Rule Name"
Get-NetFirewallProfilereturns three rows (Domain/Public/Private) each showingEnabled : True,DefaultInboundAction : Block,DefaultOutboundAction : Allow.Get-NetFirewallRulereturns a long table of active inbound rules — dozens to over a hundred is normal on a stock Windows install.Disable-NetFirewallRuleproduces no output on success.
Get-NetFirewallProfile/Set-NetFirewallProfile don't exist — these cmdlets require the NetSecurity module, present by default on Windows 8/Server 2012 and later; on Windows 7 use the netsh advfirewall commands above instead. "Cannot find a firewall rule that matches..." from Disable-NetFirewallRule means the -DisplayName string doesn't match exactly (it's case-insensitive but must match fully) — copy the exact name from the Get-NetFirewallRule output rather than retyping it.Things to try / extra points#
# Flush DNS cache (source checklists call this out explicitly)
ipconfig /flushdns
Successfully flushed the DNS Resolver Cache.- "The requested operation requires elevation" on some builds — reopen elevated.
- This command essentially never fails otherwise; if DNS problems persist afterward the issue is elsewhere (bad DNS server config, hosts file tampering — see below), not the cache itself.
# Find listening ports and tie them back to a process (kill malicious listeners)
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess | Sort-Object LocalPort
Get-Process -Id <PID>
- A table of listening ports with their owning PID.
- Common/expected ports on a default Windows box: 135 (RPC), 445 (SMB), 3389 (RDP, only if enabled), 5985 (WinRM, only if enabled).
Get-Process -Id <PID>resolves that PID to a process name and path.
Get-NetTCPConnection doesn't exist on Windows 7/Server 2008 R2 (it's PowerShell 4.0+/NetTCPIP module) — fall back to netstat -ano below. "Cannot find a process with the process Id netstat -ano
- Columns
Proto,Local Address,Foreign Address,State,PID. - Works on every Windows version back to XP — this is the reliable fallback when
Get-NetTCPConnectionisn't available.
- Output scrolls past too fast to read — pipe to a file (
netstat -ano > C:\netstat.txt) or| more. - A PID of
0next toState LISTENINGis normal for some system entries; match PIDs against Task Manager's Details tab (enable the PID column) to identify the owning process.
Tip: Cross-reference every listening PID against Task Manager's Details tab (or
Get-Process). Standard Windows processes you'll see repeatedly:System,svchost.exe,lsass.exe,services.exe,wininit.exe,spoolsv.exe. Anything unfamiliar tied to a listening port deserves a closer look — check itsGet-Process -Id <PID> | Select Pathand verify the digital signature.
# Check code-signing on a suspicious binary (built into Windows, no download needed)
Get-AuthenticodeSignature "C:\path\to\suspect.exe"
Status : Valid with a SignerCertificate showing a real publisher (e.g. Microsoft Corporation) for legitimate signed binaries.Status : NotSignedmeans the file has no digital signature at all — very common for legitimate small utilities too, so this alone isn't proof of malice, but combined with an unfamiliar name/location it's a red flag.Status : HashMismatchmeans the file was modified after signing — treat as highly suspicious. "Cannot find path" means a typo in the path; useTest-Pathor tab-completion first.
- Check the hosts file for unauthorized DNS redirection — a classic hidden-persistence trick:
Get-Content C:\Windows\System32\drivers\etc\hosts | Where-Object { $_ -notlike "#*" -and $_.Trim() -ne "" }
127.0.0.1 localhost / ::1 localhost if those are uncommented.- "Cannot find path" if the drivers\etc folder path is mistyped — it's fixed on every Windows install, so double check for a typo rather than assuming it moved.
- If you see entries mapping real domains (e.g.
windowsupdate.microsoft.com, antivirus vendor domains) to arbitrary IPs, that's a classic malware persistence/AV-blocking technique — remove those lines with Notepad (run as Administrator to save) and keep only the localhost defaults. If you find extra entries beyond the commented-out defaults, remove them (keep only the127.0.0.1 localhost/::1 localhoststyle defaults unless the README requires specific entries).
- Check for hidden port-forwarding/proxy rules and rogue static routes:
netsh interface portproxy show all
route print
portproxy show allon a clean machine usually prints an empty table (noListen on/Connect torows).route printshows the routing table with aNetwork Destination/Netmask/Gateway/Interface/Metricheader — the default route0.0.0.0should point to your actual gateway.
portproxy show allreturning entries you didn't create is the actual finding, not a failure — those are the rogue rules to remove.- An unfamiliar persistent static route (flagged differently from DHCP-assigned routes, shown near the bottom under "Persistent Routes") is likewise a finding to investigate, not a command error.
Remove unexpected port-proxy entries (
netsh interface portproxy delete v4tov4 listenport=<port> listenaddress=<addr>) and unexpected static routes (route delete <destination>).
- Disable legacy/insecure name resolution protocols that firewall rules alone don't stop:
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Name "EnableMulticast" -Value 0 -Type DWord
- No output (the
Out-Nullsuppresses theNew-Itemconfirmation,Set-ItemPropertyis silent by default). - Confirms via
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Name EnableMulticastreturning0.
- "Requested registry access is not allowed" needs an elevated console.
- This disables LLMNR (Link-Local Multicast Name Resolution), a common lateral-movement/credential-relay vector — if name resolution for local hostnames breaks afterward on a scenario that actually needs LLMNR, this is the setting to revert.
Tip: Never leave the firewall "off" while you work through the rest of the checklist "for convenience," then forget to turn it back on. Enable it early — it doesn't block your own admin activity in almost all CyberPatriot scenarios.
CIS Benchmark cross-reference: The three-profile (Domain/Private/Public), state-on/inbound-block/outbound-allow, log-everything approach in this section matches CIS Microsoft Windows 10/11 Benchmark, Level 1, "Windows Defender Firewall with Advanced Security" guidance directly.
CIS Level 1 specifies a minimum firewall log file size per profile (commonly cited around 16,384 KB) — if your logging size limit is left at Windows' tiny default, bump it up; a log that rotates too fast loses evidence you might need for forensics questions.
If the firewall configuration looks like it's been tampered with in a way that's hard to untangle rule-by-rule, resetting to Windows defaults and re-applying only what you need is often faster than auditing dozens of custom rules one at a time:
netsh advfirewall reset
Ok.- "The requested operation requires elevation" needs an elevated prompt.
- After this, the firewall is back to out-of-box defaults (state on, inbound block, outbound allow, but logging disabled and any custom rules gone) — always immediately re-run your
state on/firewallpolicy/loggingcommands from earlier in this section, since a reset without follow-up leaves logging off.
This restores default rules and profile settings — re-run your profile state/logging configuration afterward, since the reset also clears those.
- Once you're happy with the firewall configuration, export it so you have a known-good backup you can restore from without redoing everything by hand:
netsh advfirewall export "C:\firewall_backup.wfw"
:: To restore later:
netsh advfirewall import "C:\firewall_backup.wfw"
exportprintsOk.and creates a binary.wfwfile (don't try to open/edit it as text).importprintsOk.and silently replaces the entire current firewall configuration with the saved one.
- "Access is denied" needs elevation for both.
- If
importdoesn't seem to change anything, verify the.wfwpath is correct — a typo'd path fails silently in some builds rather than throwing a clear error, so re-check withTest-Path "C:\firewall_backup.wfw"in PowerShell first.
- Custom rules added outside the normal "allow an app through the firewall" flow often lack a
DisplayGroup(the category an app-installed rule normally belongs to) — filtering for that is a quick way to surface manually-added rules that might be planted:
Get-NetFirewallRule | Where-Object { -not $_.DisplayGroup -and $_.Enabled -eq "True" } | Select DisplayName, Direction, Action
DisplayGroup — these are rules created individually (by an app installer's custom action, by netsh/PowerShell directly, or manually in the GUI) rather than as part of a named Windows feature group.- A long list here isn't a command failure — it just means this image has a lot of manually-added rules, which is common on machines with lots of third-party software.
- Cross-check each
DisplayNameagainst what software is actually installed; anything referencing an unfamiliar name, a raw port number, or a suspicious path is worth disabling.
- Quick GUI-free status check without opening
wf.mscat all — useful for a fast sanity check mid-round:
netsh advfirewall show allprofiles
State OFF, that's a real finding — enable it with netsh advfirewall set <profile>profile state on or netsh advfirewall set allprofiles state on for all three at once.8. Malware & Unwanted Software Removal#
Reality check: Competition scoring images are frequently offline once the round starts, or have restricted internet. Don't build your strategy around downloading Malwarebytes/CCleaner/Spybot/Sysinternals mid-round if you haven't verified internet access is actually available and allowed. If your team practices with internet access, treat the tools below as "if available," and always have an offline (built-in tools) fallback plan — see the extra-points callouts.
GUI Tools (if internet/tools are available and permitted) — Installation & Use#
These are large, slow scans — start each one and keep working on other checklist sections while it runs rather than sitting and watching the progress bar. Do them in whatever order lets you multitask best; a common pattern is to kick off Malwarebytes first (it's usually the slowest), work on accounts/firewall/services while it runs, then handle CCleaner and Spybot's faster passes.
Malwarebytes (free edition — anti-malware scanner)
- Download from the official site, malwarebytes.com → Free Download. Don't use a mirror or search-result link you're not sure about.
- Run the installer. When it offers a Premium trial, uncheck/decline it — the free scan-and-remove functionality is everything you need, and accepting the trial just adds nag prompts.
- Let it launch after install. If it offers to update its detection database and you have internet, accept — an out-of-date scanner catches less.
- Click Scan and choose the most thorough option offered — labeled Full Scan in older versions, or just the default Scan button (which runs a full Threat Scan) in newer ones. Avoid "Quick Scan" if a more thorough option exists.
- Wait for it to finish (can take 10-30+ minutes) — go work on other sections.
- When it's done, review the results list, make sure everything found is selected, and click Quarantine/Remove Selected.
- Restart if it prompts you to, once you're at a natural stopping point.
CCleaner (free edition — junk/registry cleaner)
- Download from the official site, ccleaner.com. During install, watch for and decline any bundled extra software/toolbar offers in the installer.
- Open CCleaner. Go to the Cleaner (or Custom Clean, depending on version) tab.
- If prompted "Intelligently scan for cookies to keep," choose No — keep the pass simple and fast.
- Click Analyze, review what it found, then click Run Cleaner to clear temp/junk files.
- Switch to the Registry tab → Scan for Issues.
- Click Fix Selected Issues — it will offer to back up the change to a .reg file first. Accept this (click Yes) so you have a rollback path if fixing an entry breaks something.
- Click through and fix all listed issues.
Spybot – Search & Destroy (free "Home Use" edition — anti-spyware scanner)
- Download from the official site, safer-networking.org, selecting the free Home Use edition.
- During installation, if you're offered an install-type choice, pick the more advanced/thorough option (older versions phrase this as "I want more control, more feedback, and more responsibility") rather than the minimal default — this enables the fuller scan capability.
- After install, if prompted, check "Open Start Center" and "Check for new malware signatures," then click Finish.
- Before scanning, go to the Update tab and update definitions if internet is available.
- From the Start Center, run a System Scan.
- Let it complete (can be slow), review flagged items, select them, and remove/fix.
After running any/all of the above:
- Re-check the scoring report. These tools sometimes flag or remove things unrelated to actual scoring criteria, and can occasionally interfere with a required program — don't let an AV tool uninstall or quarantine anything the README says is required. If something required goes missing after a scan, that's the first place to look.
- Uninstall the cleaning tools themselves at the end if the scenario doesn't call for them to remain installed — leaving Malwarebytes/CCleaner/Spybot installed generally isn't a problem, but check your competition's specific guidance on staged/installed third-party tools.
Sysinternals Suite (Process Explorer, Autoruns, TCPView, Sigcheck) — portable, no installer needed
If internet access is available and permitted: download the ZIP directly from Microsoft's official Sysinternals page (learn.microsoft.com/sysinternals → Downloads → Sysinternals Suite), extract it anywhere (e.g., C:\Tools\Sysinternals), and run the executables directly — no installation step, they're portable EXEs:
- Process Explorer (
procexp64.exe) — a far more detailed Task Manager replacement; right-click any process → Check VirusTotal (needs internet) or view its full path, loaded DLLs, and digital signature at a glance. - Autoruns (
autoruns64.exe) — shows every autostart location Windows has (Run keys, services, scheduled tasks, IFEO, WMI subscriptions, and more) in one tabbed view — the single best tool for the persistence-hunting work in Section 22, when available. - TCPView (
tcpview.exe) — live GUI view of every network connection and the process behind it, a GUI alternative tonetstat -ano. - As covered earlier in this section: don't build your primary strategy around these being available, since a scoring image is frequently offline — but if your competition's rules allow pre-staging tools before the round starts, having a copy ready to go is a legitimate time-saver.
Removing Unwanted / Unauthorized Programs#
- Control Panel → Programs → Uninstall a Program. Review every entry.
- Uninstall anything not required by the README (games, P2P/torrent clients, cracking/keygen tools, remote-access tools not authorized, hacking tools, old vulnerable software versions).
- Do not uninstall required software, browsers, runtimes (.NET, Visual C++ redistributables — these are dependencies for other software), or anything explicitly listed as authorized.
- If uninstall fails with "access denied" or "in use," find and end the locking process in Task Manager (Details tab), then retry.
- Some software hides itself from the visible Uninstall list but leaves registry traces. Check both 64-bit and 32-bit uninstall keys:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select DisplayName, DisplayVersion, Publisher, UninstallString | Where-Object { $_.DisplayName }
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue |
Select DisplayName, DisplayVersion, Publisher, UninstallString | Where-Object { $_.DisplayName }
UninstallString value directly (paste it into an elevated Command Prompt/Run box) to remove it since there's no visible GUI entry to click.# Alternative enumeration (can be slow / triggers reconfig side effects on some systems — use read-only listing, avoid calling .Uninstall() unless you mean it)
Get-CimInstance -ClassName Win32_Product | Select Name, Version, Vendor
.Uninstall() scripting.Caution:
Win32_Productenumeration is known to trigger Windows Installer consistency-checking as a side effect on some systems (can be slow and, rarely, reconfigure/repair installed MSI packages). Prefer the registryUninstallkey query above for a safer read-only listing; useWin32_Productmainly when you specifically need.Uninstall()scripting against an MSI-based app.
Windows Defender Exclusions Audit#
A very common technique across CyberPatriot rounds: an exclusion gets added to Windows Defender's real-time scanning — an entire drive letter, a broad user-profile folder, or a specific "hiding spot" like C:\Users\Public — so that anything sitting there is silently never scanned. This is easy to miss because Defender otherwise still shows as "on" and "protecting" in the Security app; the exclusion list is a separate, less visible setting.
- Check every exclusion category — path, file extension, and process are all separate lists, so check all three:
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
Get-MpPreference | Select-Object -ExpandProperty ExclusionExtension
Get-MpPreference | Select-Object -ExpandProperty ExclusionProcess
- "Property ExclusionPath cannot be found" style error is unusual for this cmdlet — if seen, confirm Windows Defender itself is actually the active AV (
Get-MpComputerStatus) rather than a third-party AV having taken over, sinceGet-MpPreferencereflects Defender's own config specifically. - Any non-empty result matching the red-flag patterns listed in the bullets below is a real, high-priority finding.
- Treat any of the following as a red flag worth removing:
- An exclusion pointing at an entire drive letter (
C:\,D:\) - An exclusion pointing at a whole user profile folder (
C:\Users\<name>\) rather than one specific, justifiable application subfolder - An exclusion pointing at
Downloads,Temp,AppData\Roaming, or another common malware-drop location - A file-extension exclusion that's unusually broad (
.exe,.dll,.*) rather than something narrow and clearly justified
- An exclusion pointing at an entire drive letter (
- Remove any confirmed-bad exclusion:
Remove-MpPreference -ExclusionPath "C:\Users\Public"
Remove-MpPreference -ExclusionExtension ".exe"
Remove-MpPreference -ExclusionProcess "suspicious.exe"
Get-MpPreference queries above to confirm the entry is gone.- "Access is denied" — needs an elevated PowerShell session.
- Removing an exclusion the README/scenario actually relies on (rare, but check first if the excluded path/process name looks tied to required software) can cause that software to get flagged/quarantined afterward — if a required app breaks after removing an exclusion, that's the likely cause.
- Re-run a scan after removing exclusions — anything that was hiding behind them will only get caught on the next scan, not retroactively:
Start-MpScan -ScanType QuickScan
# Or for a more thorough (slower) pass:
Start-MpScan -ScanType FullScan
Get-MpThreatDetection or the Windows Security app's Protection History.Get-MpComputerStatus shows RealTimeProtectionEnabled: True first.Tip: Exclusions can also be enforced via Administrative Templates/Group Policy registry keys instead of the live
Get-MpPreferencesettings — ifGet-MpPreferenceshows nothing but you still suspect exclusions, also checkHKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths(and the...\Extensions/...\Processessiblings), since GPO-set exclusions can be layered on separately from what the Security app shows you.
Things to try / extra points#
Tip:
Get-Process | Sort-Object CPU -DescendingandGet-Process | Sort-Object WS -Descending(working set/memory) can surface a resource-hungry malicious process you'd otherwise miss by just eyeballing Task Manager.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 Name, Id, CPU, Path
- Some processes show blank
Patheven as Administrator — that's normal for protected system/SYSTEM-owned processes you don't have rights to inspect that deeply; not every blank path is suspicious. - Focus on unfamiliar process names, or a familiar name (e.g.
svchost.exe) running from a Path OUTSIDE its normalSystem32location — that mismatch is a much stronger signal than raw CPU usage alone.
Tip: Sysinternals tools (Process Explorer, Autoruns, TCPView, Sigcheck) are excellent for malware hunting but are not pre-installed on stock Windows and typically cannot be downloaded mid-competition if the scoring image has no internet access. If your team is allowed to stage tools before the round (check your competition's rules), pre-stage a portable copy; otherwise rely on the built-in PowerShell/CMD equivalents throughout this document (
Get-Process,Get-CimInstance Win32_StartupCommand,Get-AuthenticodeSignature, registry Run-key queries, etc.) which ship with every Windows install.
- Sweep for prohibited files — media, hacking tools, cracks — in common user-writable locations:
Get-ChildItem -Path C:\Users -Recurse -Include *.mp3,*.mp4,*.avi,*.mkv,*.wav,*.mov -ErrorAction SilentlyContinue |
Select FullName, Length | Format-Table -AutoSize
Get-ChildItem -Path C:\Users\Public, C:\ProgramData, C:\Windows\Temp -Recurse `
-Include *.mp3,*.mp4,*.avi,*.exe,*.bat,*.vbs,*.ps1 -ErrorAction SilentlyContinue
- No error mode; can be slow scanning a large
C:\Userstree — that's expected. - A hit doesn't automatically mean "delete it" — a
.mp3in a legitimately-authorized user's music folder isn't the same finding as one stashed inC:\ProgramDataorC:\Windows\Temp; judge by location and context, not just extension.
- Common CyberPatriot "prohibited items" to search for by name/keyword: nmap, Wireshark, Metasploit, Cain and Abel, netcat/nc/ncat, John the Ripper, keyloggers, LOIC/HOIC, uTorrent/BitTorrent/qBittorrent, any game titles (Steam, Minecraft, etc. unless authorized), cracking/keygen tools, TeamViewer/AnyDesk/remote-access software not authorized by README.
Get-ChildItem -Path "C:\","C:\Program Files","C:\Program Files (x86)","C:\Users" -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "nmap|wireshark|metasploit|cain|netcat|ncat|keygen|crack|nc\.exe|torrent" } |
Select FullName
- This is a genuinely slow, full-
C:\-adjacent recursive search — expect it to take a while, especially the first"C:\"path which re-scans everything the more specific paths after it already would (a bit redundant as written, but harmless, just slower than strictly necessary). - A hit on a filename merely containing "crack" (e.g. a legitimate file named
crackers_recipe.docx) is a false positive from the broad pattern match — read the actual full path/filename before treating every regex hit as confirmed contraband.
- Check for hidden secondary data streams (a way to hide payloads inside an otherwise normal file) — an advanced technique worth a quick sweep in user-writable folders:
Get-ChildItem -Path C:\Users -Recurse -Stream * -ErrorAction SilentlyContinue | Where-Object { $_.Stream -ne ':$DATA' }
:$DATA stream, so this filters down to just files WITH an extra alternate stream attached.Get-Content -Path "file.txt:StreamName".- Run the built-in System File Checker / DISM if you suspect core OS files were tampered with (safe, offline-capable):
sfc /scannow
DISM /Online /Cleanup-Image /RestoreHealth
sfc /scannow takes several minutes and ends with "Windows Resource Protection did not find any integrity violations" (clean) or a message that violations were found and repaired (or not fully repaired).- "Windows Resource Protection found corrupt files but was unable to fix some of them" means the local component store itself is damaged — run the
DISM /RestoreHealthline to repair the store first, then re-runsfc /scannow. - If
DISMalso fails with no source found and this image is offline, that specific repair may not be fully achievable — see the tip immediately below.
Tip:
DISM /RestoreHealthneeds a source of clean files; if it fails offline due to no WSUS/internet source, that's expected on an air-gapped scoring VM —sfc /scannowalone still checks and repairs from the local component store when possible.
CIS Benchmark cross-reference: Beyond the AV/cleaner tools above, CIS Level 1 has a dedicated "Windows Defender Antivirus" / "Microsoft Defender Antivirus" Administrative Templates block worth checking: real-time protection must stay on, cloud-delivered protection and automatic sample submission should be enabled, and PUA (Potentially Unwanted Application) protection should be set to Block. Check under
gpedit.msc → Computer Configuration → Administrative Templates → Windows Components → Microsoft Defender Antivirus(exact path name varies slightly by Windows version) rather than assuming defaults are fine on a vulnerable image.
# Quick check of current Defender configuration without changing anything
Get-MpPreference | Select DisableRealtimeMonitoring, MAPSReporting, SubmitSamplesConsent, PUAProtection
Get-MpComputerStatus | Select AntivirusEnabled, RealTimeProtectionEnabled, AntispywareEnabled
DisableRealtimeMonitoring: False, AntivirusEnabled/RealTimeProtectionEnabled/AntispywareEnabled all True on a healthy system.- "not recognized" on very old Windows 7-era builds without Defender's PowerShell module — use the Security Center GUI instead.
- Any
Truevalue forDisableRealtimeMonitoring, orFalseon the enabled/protection flags, is a serious, high-priority finding — fix withSet-MpPreference -DisableRealtimeMonitoring $false.
Two more CIS Level 1 Defender settings that live outside the basic on/off toggle and are easy to miss: Network Protection (blocks connections to known-malicious sites/IPs at the network level — separate from browser-based SmartScreen) and e-mail scanning (scans email attachments/content, off by default):
powershellSet-MpPreference -EnableNetworkProtection Enabled Set-MpPreference -DisableEmailScanning $falseExpected result:- Silent on success.
- Verify with
Get-MpPreference | Select EnableNetworkProtection, DisableEmailScanning.
If it fails:- "The operation requires elevation" needs an Administrator PowerShell session.
- Network Protection needs Defender's real-time protection already enabled to function — if it doesn't seem to be blocking anything, confirm real-time protection status first (checked in the query just above this bullet).
Check signature freshness — a Defender that's "on" but running on ancient virus definitions is barely better than no AV at all, and is an easy thing to overlook since the app doesn't loudly warn you:
Get-MpComputerStatus | Select AntivirusSignatureLastUpdated, AntivirusSignatureAge, AntispywareSignatureAge
If internet access is available, force an update: Update-MpSignature.
Expected result: AntivirusSignatureAge in days — low single digits is healthy.
If it fails: A large age (weeks/months) on an offline image is expected and often unfixable without internet — note it rather than looping on Update-MpSignature, which will just time out if there's genuinely no connectivity. Update-MpSignature failing with a network error confirms no internet rather than indicating a broken command.
- Check Defender's own detection history — if it already caught and quarantined something, that's often the fastest way to find out what the "planted malware" for this round actually was, without doing a from-scratch file sweep:
Get-MpThreatDetection
Get-MpThreat
- If a forensics question gives you a known-bad file hash to search for, compare it directly instead of relying on Defender to have already caught it:
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
Get-FileHash -Algorithm SHA256 -ErrorAction SilentlyContinue |
Where-Object { $_.Hash -eq "PUT_KNOWN_BAD_HASH_HERE" }
C:\ hash-everything operation — the tip right below already flags this; narrow -Path if you have any lead on where to look, since hashing every file on the drive can take a long time.This is a slow, whole-disk operation — narrow the
-Pathto a specific folder if you have any idea where to look first.
9. Services Hardening#
Open via services.msc (Start → type it) or MMC → Add/Remove Snap-in → Services. Sort by name and compare against the table below. If a service isn't listed here, don't panic — research it (executable path, description, install date) rather than guessing.
README always wins. If a scenario requires Remote Desktop, print sharing, IIS, SQL Server, etc. for a stated business reason, leave the relevant service(s) running and don't blindly disable per this table.
| Service Name | Recommended State |
|---|---|
| ActiveX Installer | Disabled |
| Adaptive Brightness | Disabled |
| Application Experience | Manual |
| Application Identity | Manual |
| Application Information | Manual |
| Application Layer Gateway Service | Disabled |
| Background Intelligent Transfer Service | Manual |
| Base Filtering Engine | Automatic |
| BitLocker Drive Encryption Service | Manual |
| Bitlocker Level Backup Engine Service | Disabled |
| Bluetooth Support Service | Disabled (unless Bluetooth is required) |
| Certificate Propagation | Disabled |
| CNG Key Isolation | Manual |
| COM+ Event System | Manual |
| COM+ System Application | Manual |
| Computer Browser | Manual/Disabled |
| Credential Manager | Manual |
| Cryptographic Services | Automatic |
| DCOM Server Process Launcher | Automatic |
| Desktop Window Manager Session Manager | Automatic |
| DHCP Client | Automatic |
| Diagnostic Policy Service | Automatic |
| Diagnostic Service Host | Manual |
| Diagnostic System Host | Manual |
| Disk Defragmenter | Disabled |
| Distributed Link Tracking Client | Manual |
| Distributed Transaction Coordinator | Manual |
| DNS Client | Automatic |
| Encrypting File System | Manual |
| Extensible Authentication Protocol | Manual |
| Fax | Disabled |
| Function Discovery Provider Host | Manual |
| Function Discovery Resource Publication | Manual |
| Group Policy Client | Automatic |
| Health Key and Certificate Management | Manual |
| HomeGroup Listener | Disabled |
| HomeGroup Provider | Disabled |
| Human Interface Device Access | Disabled |
| IKE and AuthIP IPsec Keying Modules | Manual |
| Interactive Services Detection | Disabled |
| Internet Connection Sharing | Disabled |
| IP Helper | Manual |
| IPsec Policy Agent | Manual |
| KtmRm for Distributed Transaction Coordinator | Disabled |
| Link-Layer Topology Discovery Mapper | Manual |
| Microsoft .NET Framework NGEN v2.0 | Manual |
| Microsoft iSCSI Initiator Service | Disabled |
| Microsoft Software Shadow Copy Provider | Disabled |
| Multimedia Class Scheduler | Disabled |
| Net.Tcp Port Sharing Service | Disabled |
| Netlogon | Disabled (unless domain-joined and required) |
| Network Access Protection Agent | Manual |
| Network Connections | Manual |
| Network List Service | Manual |
| Network Location Awareness | Manual |
| Network Store Interface Service | Automatic |
| Parental Controls | Disabled |
| Peer Name Resolution Protocol | Disabled |
| Peer Networking Grouping | Disabled |
| Peer Networking Identity Manager | Disabled |
| Performance Logs & Alerts | Manual |
| Plug and Play | Automatic (caution: source list said Disabled — do NOT disable this; PnP is required for hardware to function. Treat this as an error in the historical checklist and leave PnP on its default Automatic setting.) |
| PNP-X IP Bus Enumerator | Disabled |
| PNRP Machine Name Publication Service | Disabled |
| Portable Device Enumerator Service | Disabled |
| Power | Automatic |
| Print Spooler | Disabled (unless printing is required — then Automatic) |
| Problem Reports and Solutions Control Panel Support | Manual |
| Program Compatibility Assistant Service | Manual |
| Protected Storage | Manual |
| Quality Windows Audio Video Experience | Disabled |
| Remote Access Auto Connection Manager | Disabled |
| Remote Access Connection Manager | Disabled |
| Remote Desktop Configuration | Disabled (unless RDP required) |
| Remote Desktop Services | Disabled (unless RDP required) |
| Remote Procedure Call (RPC) | Automatic (never disable — required for the OS to function) |
| Remote Procedure Call (RPC) Locator | Manual |
| Remote Registry | Disabled |
| RIP Listener | Disabled |
| Routing and Remote Access | Disabled |
| RPC Endpoint Mapper | Automatic (never disable) |
| Secondary Logon | Disabled |
| Secure Socket Tunneling Protocol Service | Disabled |
| Security Accounts Manager | Automatic (never disable) |
| Security Center | Automatic |
| Server | Disabled (unless file/print sharing is required) |
| Shell Hardware Detection | Disabled |
| Smart Card | Disabled (unless smart cards required) |
| Smart Card Removal Policy | Disabled |
| SNMP Trap | Disabled |
| Software Protection | Automatic |
| SPP Notification Service | Manual |
| SSDP Discovery | Disabled |
| Superfetch / SysMain | Manual |
| System Event Notification Service | Automatic |
| Tablet PC Input Service | Disabled |
| Task Scheduler | Automatic (needed for many legitimate OS/maintenance tasks and for you to audit scheduled tasks — do not disable; audit its contents instead, see Section 21) |
| TCP/IP NetBIOS Helper | Disabled |
| Telephony | Disabled |
| Telnet | Disabled |
| Themes | Manual |
| Thread Ordering Server | Manual |
| TP AutoConnect Service | Disabled |
| TP VC Gateway Service | Disabled |
| TPM Base Services | Disabled (unless BitLocker/TPM features required) |
| UPnP Device Host | Disabled |
| User Profile Service | Automatic (never disable — required for login) |
| Virtual Disk | Manual |
| VMware Tools / VMware Snapshot Provider | Automatic/Manual (leave running in virtualized competition images — required for the environment itself) |
| Volume Shadow Copy | Manual (leave Automatic/Manual, not fully disabled, if System Restore/backups are in use) |
| WebClient | Disabled |
| Windows Audio | Automatic |
| Windows Audio Endpoint Builder | Automatic (source list said Disabled — needed alongside Windows Audio for sound; keep Automatic unless you intend to fully silence the box) |
| Windows Backup | Manual |
| Windows Biometric Service | Disabled (unless biometrics required) |
| Windows CardSpace | Disabled |
| Windows Color System | Disabled |
| Windows Connect Now | Disabled |
| Windows Defender / Microsoft Defender Antivirus | Automatic — never disable |
| Windows Driver Foundation | Manual |
| Windows Error Reporting Service | Manual |
| Windows Event Collector | Disabled |
| Windows Event Log | Automatic (never disable — you need this for forensics/scoring) |
| Windows Firewall | Automatic — never disable |
| Windows Font Cache | Manual (leave enabled; disabling can cause rendering slowdowns) |
| Windows Image Acquisition | Disabled (unless scanners/cameras required) |
| Windows Installer | Manual |
| Windows Management Instrumentation | Automatic (never disable — required for most of the PowerShell/WMI commands in this document) |
| Windows Media Player Network Sharing Service | Disabled |
| Windows Modules Installer | Manual |
| Windows Remote Management (WinRM) | Disabled (unless remote management required) |
| Windows Search | Automatic (leave default; disabling only saves resources, not security) |
| Windows Time | Manual/Automatic |
| Windows Update | Automatic |
| WinHTTP Web Proxy Auto-Discovery Service | Disabled |
| Wired AutoConfig | Manual |
| WLAN AutoConfig | Manual (Automatic if Wi-Fi is the primary connection) |
| WMI Performance Adapter | Disabled |
| Workstation | Automatic |
| WWAN AutoConfig | Manual |
Correction note: Two entries in the historical source table (Plug and Play = Disabled, Windows Audio Endpoint Builder = Disabled) would break basic OS functionality if actually applied and are flagged above as likely transcription errors from the original document — do not disable Plug and Play or fully break audio unless you have a specific reason to.
Explicitly call out (from source material) as commonly-needed-to-disable, non-default services if present: SMTP, Bonjour, Remote Access Auto Connection Manager, Remote Access Connection Manager, Remote Desktop Configuration, Remote Desktop Services, Remote Registry, RIP Listener, World Wide Web Publishing Service (indicates IIS is running), NetMeeting Remote Desktop Sharing, Simple File Sharing, SSDP Discovery, Windows Messenger Service.
Modern/Optional Services Not on the Classic List (CIS-confirmed gaps)#
The service table above traces back to an older Windows 7/8-era baseline and misses several services that ship on modern Windows 10/11 images and are explicitly called out in the current CIS Windows Benchmark:
- OpenSSH Server (
sshd) —(L1)should be uninstalled/disabled unless explicitly required. This is an optional Windows feature (Settings → Apps → Optional Features) that, once enabled, opens a full SSH remote-access path into the box — a real and easily-missed backdoor since competitors instinctively check RDP but often forget Windows ships its own SSH server option.powershellGet-WindowsCapability -Online | Where-Object Name -like "OpenSSH.Server*" Get-Service sshd -ErrorAction SilentlyContinue # If present and not required: Stop-Service sshd; Set-Service sshd -StartupType Disabled Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 - Windows Subsystem for Linux (
LxssManager) —(L1)should be disabled unless required. WSL gives a full Linux userland running alongside Windows, which is both a legitimate attack-surface expansion and a way to run Linux tools that Windows-only security tooling won't see.Expected result:powershellGet-Service LxssManager -ErrorAction SilentlyContinue Set-Service LxssManager -StartupType Disabled -ErrorAction SilentlyContinueGet-Serviceshows current status if WSL/LxssManager is installed, or nothing (suppressed error) if it isn't — most client images won't have it at all.Set-Serviceis silent on success. If it fails: No error mode given the suppression flag; absence is the common case and means this bullet is a no-op, not a failure.
Command-Line Method#
# See everything currently running — fastest way to spot something unexpected
Get-Service | Where-Object { $_.Status -eq "Running" } | Select-Object Name, DisplayName | Sort-Object Name
# Disable and stop a specific service
Set-Service -Name "RemoteRegistry" -StartupType Disabled -Status Stopped
Set-Service -Name "TlntSvr" -StartupType Disabled -Status Stopped
- First command lists all running services alphabetically.
Set-Servicecalls are silent on success.
sc query state= all
sc qc <servicename>
sc config <servicename> start= disabled
sc stop <servicename>
sc query lists every service with its state; sc qc shows one service's configuration (binary path, start type, display name); sc config/sc stop are silent or print [SC] ChangeServiceConfig SUCCESS.sc config's syntax is famously picky about spacing — the space after start= (and every key=) is required, start=disabled (no space) fails with a syntax error while start= disabled (with space) works; this trips up almost everyone the first time they use sc.exe. "Access is denied" needs elevation. "OpenService FAILED 1060: The specified service does not exist" means a typo'd <servicename> — get exact names from sc query state= all first.Spoofed / Impersonating Service Names#
A recurring planted-vulnerability pattern: a malicious service is given a name deliberately similar to a real Windows service — a fake variant of svchost, a near-duplicate of a legitimate service's display name with a typo, or a service with a vague, self-referential description (e.g. "Provides service functionality" that doesn't actually describe anything). At a glance in services.msc these blend right in with the ~150 legitimate entries.
- Pull name, display name, executable path, and the account it runs as all together, so you can eyeball inconsistencies in one table instead of clicking into each service's Properties individually:
Get-CimInstance Win32_Service | Select-Object Name, DisplayName, PathName, StartName | Sort-Object Name
- Cross-reference the executable path against where it should be — genuine core Windows services run from
C:\Windows\System32\(or occasionallyC:\Windows\SysWOW64\), not from a user profile,AppData,ProgramData, or a temp folder:
Get-CimInstance Win32_Service | Where-Object { $_.PathName -and $_.PathName -notmatch '^"?C:\\Windows\\(System32|SysWOW64)' -and $_.PathName -notmatch '^"?C:\\Program Files' } |
Select-Object Name, DisplayName, PathName, StartName
This will also catch legitimately-installed third-party services (antivirus, VMware Tools, printer drivers) — the point isn't that every result is bad, it's that this list is now small enough to actually review by eye instead of scrolling past 150 entries. Expected result: A shorter list than the full table — mostly legitimate third-party software as the callout notes. If it fails: No error mode; a hit running from
AppData, a temp folder, orC:\Users\Public(rather than a recognizable Program Files subfolder for known software) is the pattern actually worth chasing.
- Check the digital signature on anything that looks even slightly off — a real Microsoft service binary will show a valid Microsoft signature:
Get-AuthenticodeSignature "C:\Windows\System32\suspicious_svc.exe" | Select Status, SignerCertificate
Status: Valid with a SignerCertificate showing a Microsoft (or other recognized vendor) subject for legitimate software.Status: NotSigned or HashMismatch on something claiming to be a core Windows component is a serious, high-priority finding. "Cannot find path" just means you need the actual path from the earlier PathName query, not the literal placeholder shown here.- Services running under an unusual account are worth a second look — most legitimate services run as
LocalSystem,NT AUTHORITY\LocalService,NT AUTHORITY\NetworkService, or a properNT SERVICE\<name>virtual account, not as a specific named user (especially not an Administrator account):
Get-CimInstance Win32_Service | Where-Object { $_.StartName -and $_.StartName -notmatch 'LocalSystem|NT AUTHORITY|NT SERVICE' } |
Select-Object Name, DisplayName, StartName
Things to try / extra points#
Tip: For any service you don't recognize, right-click → Properties → check the Path to Executable. Type that path into
Get-AuthenticodeSignatureor just navigate to the folder in Explorer (don't double-click it) and check the file's Properties → Digital Signatures tab. An unsigned binary running as a "service" in a weird folder (C:\Users\...\AppDatainstead ofC:\Windows\System32orC:\Program Files\...) is a strong malware indicator.
Get-CimInstance Win32_Service | Select Name, DisplayName, State, StartMode, PathName | Sort-Object State -Descending
State puts "Running" ahead of "Stopped").- Services with
StartMode = Autobut currentlyState = Stoppedare worth a glance — that mismatch can mean the service crashed, was manually stopped after being tampered with, or is misconfigured in a way that's itself the vulnerability being scored:
Get-CimInstance Win32_Service | Where-Object { $_.StartMode -eq "Auto" -and $_.State -eq "Stopped" } | Select Name, DisplayName, PathName
Get-EventLog/Get-WinEvent for why it stopped (crash vs. manual stop) before just restarting it blindly — if it crashed due to tampering, restarting without fixing the underlying cause just means it crashes again.- Hunt for unquoted service path vulnerabilities — a classic privilege-escalation flaw where a service path with spaces and no quotes lets an attacker plant an executable earlier in the path:
Get-CimInstance Win32_Service | Where-Object { $_.PathName -notlike '"*' -and $_.PathName -like '* *' } |
Select-Object Name, PathName
PathName in quotes via the registry ImagePath value at HKLM:\SYSTEM\CurrentControlSet\Services\<ServiceName>, then restart the service to confirm it still starts correctly with the quoted path.Tip: A blank/missing service Description field is unusual for genuine Microsoft services — the original checklist author's rule of thumb ("Microsoft is meticulous about descriptions; a missing one is suspicious") is a reasonable heuristic, not a guarantee. Verify with signature checks too.
CIS Benchmark note: Unlike the Account/Audit/Security Options sections above, the CIS Windows Benchmark does not publish a comprehensive "which services should be on/off" table like the one in this section — service hardening of this kind is more of a general security-hygiene practice (closer to Microsoft's own Security Compliance Toolkit baselines) than a specific CIS control. Don't expect to find a 1:1 citation for every row in the Services table above; treat that table as community-sourced practical guidance rather than a CIS-derived standard.
10. Startup Programs#
GUI Method#
- Windows 7/8:
msconfig→ Startup tab. - Windows 8.1/10/11: Task Manager → Startup tab (or Startup Apps in Settings on Win11).
- Only expected/required items should remain enabled — e.g., legitimate virtualization tools if this is itself a VM guest, an authorized antivirus, or software explicitly required by the README. Disable everything else.
- For anything suspicious, note its name and file path, research it, and remove/uninstall the underlying program if it's confirmed unwanted (see Section 8).
Command-Line Method#
Get-CimInstance Win32_StartupCommand | Select Name, Command, Location, User
wmic startup get Caption,Command,Location,User
wmic interface.wmic is removed by default starting Windows 11 24H2 — if "not recognized," rely on the PowerShell Get-CimInstance version above instead.Things to try / extra points#
- Startup entries also live in the registry Run keys — check all of these, not just msconfig/Task Manager's view (some malware writes directly to the registry and doesn't always surface cleanly in the GUI):
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*" -ErrorAction SilentlyContinue
Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run*" -ErrorAction SilentlyContinue
Get-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*" -ErrorAction SilentlyContinue
- No error mode given the suppression flag.
- This only checks the currently logged-in user's
HKCU— a different user's Run entries require loading their hive (reg load HKU\Temp C:\Users\<user>\NTUSER.DAT) or logging in as them directly to check via their ownHKCU.
- Also check the Startup folders directly (shortcuts placed here run at logon without needing a registry entry):
Get-ChildItem "C:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
Get-ChildItem "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
.lnk/executable files in each user's personal Startup folder and the shared all-users one — often empty or with just one or two legitimate shortcuts.Tip: Anything referencing
nc.exe,netcat,ncat,bfk,telnet, or an obfuscated/base64-looking command line in a Run key is an immediate red flag — remove the registry value (Remove-ItemProperty) and delete the referenced file.
- Don't stop at
Run— check the relatedRunOnceandRunOnceExkeys too. These are meant for one-time setup tasks that self-delete after running, but malware sometimes (ab)uses them the same way asRunfor a slightly less obvious persistence spot:
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ErrorAction SilentlyContinue
Get-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ErrorAction SilentlyContinue
RunOnce entries are typically transient (installer post-reboot steps) and self-delete after firing, so persistent entries sitting here are more unusual than in the regular Run key.Run key entry precisely because RunOnce isn't meant to accumulate persistent entries.Typing
shell:startuporshell:common startupdirectly into the File Explorer address bar jumps straight to the current user's or all-users' Startup folder — a faster GUI alternative to typing out the fullAppData\Roaming\...path from Section 10's command-line method.If a Startup folder shortcut (
.lnkfile) looks legitimate by name but you want to confirm what it actually launches, check its Properties → Shortcut tab → Target field, or read it via PowerShell — a shortcut's displayed icon/name can be completely disconnected from what it really points to:
$sh = New-Object -ComObject WScript.Shell
$sh.CreateShortcut("C:\Users\Public\Desktop\SomeShortcut.lnk").TargetPath
- "Cannot find path" — use the real
.lnkpath from your Startup-folder listing above, not the placeholder. - If
TargetPathshows something wildly different from what the shortcut's name/icon suggests (e.g. named "Adobe Update" but targetingpowershell.exe -enc <base64>), that's a serious, high-priority finding.
- See Section 22 for deeper persistence hunting (Winlogon hijacks, IFEO debugger hijacks, AppInit_DLLs, WMI event subscriptions) that goes beyond what msconfig/Task Manager will ever show you.
11. Windows Updates#
- Control Panel → System and Security → Windows Update → Change settings → set to Install updates automatically (or the strongest option your README/scenario allows).
- Click Check for Updates and install everything available, if internet access is available and the scenario allows it.
- Before restarting to apply updates, make sure you know the admin password and have taken a fresh restore point / noted your progress — some rounds are timed and a bad restart costs you time.
- Service Packs are a Windows 7-and-earlier concept; Windows 10/11 roll everything into cumulative updates — don't waste time hunting for a "service pack" on modern images.
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 20
InstalledOn for some entries is a known cosmetic quirk, not an error — cross-check with Get-CimInstance Win32_QuickFixEngineering for an alternate view if dates matter for a forensics answer.wmic qfe list brief /format:table
wmic interface.wmic is removed by default on Windows 11 24H2+ — use the PowerShell Get-HotFix version above instead if "not recognized."Why this matters right now, not just in principle: Microsoft's August 2026 Patch Tuesday alone fixed roughly 400 vulnerabilities, including a Windows Ancillary Function Driver (WinSock) elevation-of-privilege flaw (CVE-2026-68820) that was actively exploited before a patch existed, and a critical Microsoft QUIC remote-code-execution bug (CVE-2026-62815, CVSS 9.8) reachable with no authentication. "Fully updated" isn't a checkbox for its own sake — a single missed monthly cumulative update can leave one of these open.
Get-HotFix/wmic qfeabove is how you actually verify updates installed, not just that the setting says "automatic."
Things to try / extra points#
Tip: If the scoring VM has no internet access, Windows Update literally cannot download anything — don't burn time repeatedly clicking "Check for updates." Confirm connectivity first (
Test-NetConnection, or just try a browser) and move on to other sections if updates truly aren't reachable. Many CyberPatriot images intentionally have some updates missing that cannot be resolved without internet, and partial credit for "Automatic Updates enabled" as a setting is still worth doing regardless of whether updates can download.
Test-NetConnection -ComputerName 8.8.8.8 -InformationLevel Detailed
PingSucceeded: True with round-trip time stats if internet is reachable.PingSucceeded: Falseconfirms no internet — stop trying to download updates/tools and move to other sections, exactly as the tip above recommends.- If ICMP is specifically blocked but other traffic isn't, this can give a false "no internet" reading — cross-check with
Test-NetConnection -ComputerName 8.8.8.8 -Port 443(TCP-based) if you suspect ping alone is misleading.
Verify Windows Update the service is running/Automatic (see Section 9) — a disabled Windows Update service is sometimes the actual vulnerability being scored, independent of whether updates can download.
Windows 10/11 also uses a separate Update Orchestrator Service (
UsoSvc) alongside the classic Windows Update service — check both, since disabling just one can leave updates silently non-functional even though "Windows Update" itself shows as running:
Get-Service -Name wuauserv, UsoSvc | Select Name, DisplayName, Status, StartType
Disabled for StartType (Windows Update itself is often Manual/on-demand even when healthy — that's normal, not a finding by itself).- "Cannot find any service with service name 'UsoSvc'" on very old builds (pre-Windows 10) — this service doesn't exist there, ignore it.
StartType: Disabledon either is a real finding — fix withSet-Service <name> -StartupType Manual(their normal default state).
- If "Check for updates" in the Settings app seems stuck or unresponsive,
UsoClient StartScantriggers the same scan from the command line and sometimes un-sticks a hung GUI check:
UsoClient StartScan
- "not recognized" on very old builds where this tool doesn't exist — just use the Settings app's "Check for updates" button instead.
- This command genuinely gives no feedback either way, so the only way to confirm it worked is watching the Settings app UI change state.
- A pending update that needs a reboot to finish applying can itself look like "updates aren't working" — check for a pending-reboot flag before assuming something's broken:
Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"
Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
True/False for each — True means a reboot is pending to finish applying an already-installed update.- No error mode; these are simple existence checks.
- If either is
True, reboot when you're at a natural stopping point (per the Snapshot Checkpoint note below) rather than assuming updates are stuck.
- Review Windows Update's own event log for install failures or blocked updates instead of guessing why an update didn't apply:
Get-WinEvent -LogName "Microsoft-Windows-WindowsUpdateClient/Operational" -MaxEvents 30 -ErrorAction SilentlyContinue |
Select TimeCreated, Id, Message
- "No events were found" (suppressed by the error action flag) just means nothing's happened recently in this log — not a broken command.
- A recurring failure Event ID is worth searching by that specific number for the actual error meaning.
Snapshot Checkpoint: Installing updates can trigger a reboot, and a reboot is exactly when an earlier broken change (bad service, bad UAC/RDP setting) surfaces as a hard lockout you can't easily fix while offline. Snapshot before you kick off updates or restart, so a bad reboot doesn't strand you.
12. User Account Control (UAC)#
GUI Method#
- Control Panel → System and Security → Action Center → Change User Account Control settings.
- Move the slider to the top ("Always notify") and click OK (not just close the window — closing without OK discards the change).
Registry / Command-Line Method#
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 2 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "PromptOnSecureDesktop" -Value 1 -Type DWord
EnableLUA changes to fully take effect (the other two apply more immediately but a fresh session is the safest way to confirm all three).- "Access is denied" needs elevation.
- If UAC behavior doesn't seem to change after logging back in, verify with the read-back query further down this section rather than assuming the setting didn't apply — sometimes it's just that you're testing from a session that started before the change.
Things to try / extra points#
Tip:
EnableLUA = 0(UAC fully off) is a very common planted vulnerability — always verify it's1. A machine with UAC disabled will also silently let a lot of the "run as administrator" prompts you'd normally expect just not happen, which is itself a clue something's off if you notice it.
Tip:
ConsentPromptBehaviorAdminvalues:0= elevate without prompting (bad),2= prompt for consent on secure desktop (recommended default),5= prompt for consent for non-Windows binaries. Verify it isn't0.
CIS Benchmark cross-reference: Every registry value set in this section maps 1:1 to a named CIS Microsoft Windows 10/11 Benchmark, Level 1 "User Account Control:" Security Option (Admin Approval Mode, elevation prompt behavior for admins/standard users, detect app installations, secure desktop prompting, virtualize file/registry writes) — see the full list already in Section 6's table.
- A closely related CIS Level 1 control worth checking alongside UAC: Windows Installer → "Always install with elevated privileges" should be Disabled. If it's Enabled (for both the Computer Configuration and User Configuration versions of the setting), any user — including a standard, non-admin account — can install an MSI package with full SYSTEM privileges, which is a direct and well-known privilege-escalation path that UAC alone won't stop.
# Check both halves of the "Always install with elevated privileges" setting (both must exist and be 0/absent to be safe)
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer" -Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue
Get-ItemProperty "HKCU:\SOFTWARE\Policies\Microsoft\Windows\Installer" -Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue
AlwaysInstallElevated: 0.1 on EITHER key (both must be 1 for the vulnerability to actually be exploitable, but either being 1 is worth fixing) is a serious, high-priority finding — fix with Set-ItemProperty ... -Value 0 -Type DWord on whichever key showed 1, creating the key with -Force if it doesn't exist yet but you're setting it explicitly.- There's a fifth, easy-to-miss UAC registry value:
FilterAdministratorTokencontrols whether Admin Approval Mode applies to the built-in Administrator account specifically (separate fromEnableLUA, which controls UAC for everyone else). If this is0, the built-in Administrator account silently runs with full, un-prompted elevation even with UAC otherwise on:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "FilterAdministratorToken" -Value 1 -Type DWord
- No special error mode beyond permissions.
- Once set, the built-in
Administratoraccount will itself now see UAC consent prompts like any other admin — expected behavior, not a bug, if you notice the built-in Administrator suddenly getting prompted where it didn't before.
If the Control Panel slider feels unreliable or is missing on your build,
secpol.msc → Local Policies → Security Optionshas the same UAC settings as named policies (see Section 6) — a more direct path if the Action Center GUI is being uncooperative.Verify all the values actually took, in one readable pass, rather than trusting that each
Set-ItemPropertycommand silently succeeding means the setting is correct:
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" |
Select EnableLUA, ConsentPromptBehaviorAdmin, PromptOnSecureDesktop, FilterAdministratorToken
EnableLUA: 1, ConsentPromptBehaviorAdmin: 2, PromptOnSecureDesktop: 1, FilterAdministratorToken: 1 if every earlier setting in this section landed correctly.$null means that specific property was never set (still at OS default, which for EnableLUA/PromptOnSecureDesktop is usually already the secure value — but don't assume, always confirm with this read-back rather than trusting the Set-ItemProperty calls silently succeeding).13. Network Shares#
GUI / Command-Line Method#
net share
C$, ADMIN$, IPC$) alongside any custom ones.- For every share not required, delete it:
net share <sharename> /delete
- "The network connection could not be found" if the share name has a typo — get exact names from bare
net sharefirst. - Deleting a share that turns out to be required breaks whatever depended on it — re-share it with
net share <name>=<path>if you need to undo this.
- Shares ending in
$are hidden administrative/default shares —IPC$,C$,ADMIN$are default Windows shares andIPC$regenerates on reboot regardless. Only remove non-default, unauthorized shares unless the README explicitly says to strip default admin shares too (this can break some legitimate remote administration).
PowerShell Method#
Get-SmbShare
Get-SmbShare | Where-Object { $_.Name -notlike "*$" }
Remove-SmbShare -Name "ShareName" -Force
Get-SmbSharelists all shares; the filtered version excludes default$-suffixed admin shares.Remove-SmbShare -Forceis silent on success.
- "not recognized" on very old builds (pre-Windows 8/2012) — use
net share/net share ... /deleteinstead. - A custom share deliberately named to end in
$(a hiding trick) will be filtered OUT by the second command — always review the FULL unfilteredGet-SmbSharelist too, not just the filtered view, or you'll miss exactly the kind of share this section warns about.
- Also check share-level permissions on anything that must remain shared — make sure
Everyone: Full Controlisn't set on a share that should be restricted:
Get-SmbShareAccess -Name "ShareName"
Everyone: Full).- "Cannot find the share" — use an exact name from
Get-SmbShare. Everyone: Fullon a share that should be restricted is the classic finding — fix withGrant-SmbShareAccess/Revoke-SmbShareAccess, or via the Sharing tab in Explorer's folder Properties.
Things to try / extra points#
Tip:
shrpubw(Share a Folder Wizard) is a fast GUI alternative for creating a properly permissioned share if the README requires you to create one for a specific business reason — don't just use "Everyone/Full Control" defaults.
- Harden SMB itself, not just individual shares:
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Disabled (may need a reboot to fully complete despite -NoRestart); the signature requirement is silent on success.- "Feature name is unknown" — confirm the exact name with
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocolfirst; naming can differ slightly across builds. - If an old device on the network genuinely needs SMBv1, this will break connectivity to it — rare in a competition scenario but worth a moment's thought before applying.
SMBv1 is obsolete and vulnerable (EternalBlue/WannaCry-class exploits) — disabling it is safe on essentially every modern image and is a strong, low-risk point-scoring action.
- Another CIS Level 1 SMB control worth setting alongside SMB1 removal: LanmanWorkstation → "Enable insecure guest logons" should be Disabled. When enabled, this setting lets the SMB client silently fall back to unauthenticated guest access against a remote share instead of failing — a subtle vulnerability that has nothing to do with your own shares, but with how this machine connects to others.
Set-SmbClientConfiguration -EnableInsecureGuestLogons $false -Force
- Silent on success.
- Verify with
Get-SmbClientConfiguration | Select EnableInsecureGuestLogons.
Snapshot Checkpoint: The next section disables Remote Desktop and Remote Assistance. If you are currently connected to this machine over RDP rather than sitting at its console, disabling RDP here can disconnect you and lock you out of your own session. Confirm you have local/console access (or another authorized admin who does) before proceeding, and take a snapshot first regardless — this is one of the easiest ways to accidentally strand your own team mid-round.
14. Remote Desktop & Remote Access#
GUI Method#
- Right-click This PC/My Computer → Properties → Remote settings (or Advanced System Settings → Remote tab).
- Uncheck Allow Remote Assistance connections to this computer.
- Set Remote Desktop to Don't allow connections to this computer — unless the README explicitly requires RDP access for a stated user/reason, in which case use the most restrictive allowed option (e.g., "Allow connections only from computers running Remote Desktop with Network Level Authentication").
- Apply, OK.
Registry / Command-Line Method#
# Disable RDP entirely
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 1 -Type DWord
# If RDP must stay enabled, at least require Network Level Authentication
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 1 -Type DWord
# Disable Remote Assistance and RDP shadowing/monitoring
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Remote Assistance" -Name "fAllowToGetHelp" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "Shadow" -Value 0 -Type DWord
-Force to create it.Things to try / extra points#
CIS Benchmark cross-reference: The full Remote Desktop Services Administrative Templates block in Section 24's appendix (Do not allow drive/COM port/LPT port/smart card redirection, Always prompt for a password, Require secure RPC communication, Require user authentication with NLA, Set client connection encryption level: High) is drawn directly from CIS Microsoft Windows 10/11 Benchmark, Level 1 RDS guidance — if RDP is required by your scenario, that block is the fastest way to harden it without disabling it outright.
Tip: If RDP is required by the README, verify who's allowed in via the Remote Desktop Users group (see Section 3) — an unauthorized member there is a classic vulnerability even when RDP itself is legitimately needed.
- Check for third-party remote access tools too (TeamViewer, AnyDesk, VNC, LogMeIn, Chrome Remote Desktop) — these bypass Windows' own RDP controls entirely and are common "unauthorized remote access" plants. Uninstall unless authorized.
Get-Process | Where-Object { $_.ProcessName -match "teamviewer|anydesk|vnc|logmein" }
Get-Service | Where-Object { $_.DisplayName -match "TeamViewer|VNC|AnyDesk" }
Where-Object filters a list down to only the items matching a condition. $_.ProcessName means "this process's name." -match checks against a regex pattern, and the | (pipe) characters inside the quotes mean "or" — so this reads as "keep any process whose name contains teamviewer, OR anydesk, OR vnc, OR logmein," catching several remote-access tools with one line instead of four separate checks.
15. Data Execution Prevention & Exploit Mitigations#
GUI Method (DEP)#
- Control Panel → view by Small Icons → System → Advanced system settings → Performance section → Settings → Data Execution Prevention tab.
- Select Turn on DEP for all programs and services except those I select, and leave the exceptions list empty unless a required program genuinely needs an exception (rare, and should be justified by the README).
Command-Line / System-Wide Mitigations#
# Turn on the major system-wide exploit mitigations in one shot (DEP, SEHOP, ASLR-related force relocation, etc.)
Set-ProcessMitigation -System -Enable DEP, EmulateAtlThunks, SEHOP, ForceRelocateImages
This is one cmdlet turning on four separate exploit-mitigation features system-wide at once, comma-separated in a single -Enable list: DEP (blocks code from running in memory marked "data only"), SEHOP (protects a specific Windows exception-handling mechanism attackers abuse), and ForceRelocateImages (a stronger form of ASLR, randomizing where programs load in memory so exploits can't predict addresses).
- Silent on success.
- Verify with
Get-ProcessMitigation -System.
- "not recognized" on Windows 7/early 8 — this cmdlet needs Windows 8.1+; use the DEP GUI method above as the fallback on older builds.
- Rarely breaks legitimate software on a modern OS, but if an older required application starts crashing after this, DEP/mitigation incompatibility is worth checking first via that app's own compatibility settings.
# Protect LSASS memory from credential-dumping tools (e.g., Mimikatz-style attacks)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 -Type DWord
- No common error beyond permissions.
- Can interfere with legitimate security/monitoring tools or some VPN clients that hook LSASS — test required functionality after rebooting.
# CIS Level 1 (MS Security Guide): disable WDigest, which caches a reversible plaintext-equivalent
# copy of the logon password in LSASS memory purely for backward compatibility with old auth schemes.
# This is one of the very first things a credential-dumping tool checks for.
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" -Name "UseLogonCredential" -Value 0 -Type DWord
- "Cannot find path" if the
WDigestkey doesn't exist yet — add-Force. - Extremely low functional risk; WDigest auth is legacy and rarely relied upon by anything modern.
# CIS Level 1 (MSS Legacy): force Safe DLL Search Mode, which searches the system directories
# before the current working directory when an app loads a DLL by name — blocks a classic DLL
# hijacking/planting technique where malware drops a same-named malicious DLL next to a legit exe.
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "SafeDllSearchMode" -Value 1 -Type DWord
0 on this specific image, that's a real finding since it's an unusual thing to have deliberately disabled.# CIS Level 1 (Administrative Templates > System > Early Launch Antimalware): make sure the
# Early-Launch Antimalware boot driver only allows Good/Unknown drivers (or Good/Unknown/Bad-but-critical)
# to load at boot — this stops a malicious or unsigned boot-start driver from loading before AV can scan it.
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\EarlyLaunch" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\EarlyLaunch" -Name "DriverLoadPolicy" -Value 3 -Type DWord
- Silent on success; both commands run with no output.
- Takes effect on next boot.
- "Access is denied" if not run elevated.
- Value
3= Good/Unknown/Bad-but-critical (the balanced default);1= Good only (strictest, can block legitimate but unsigned boot drivers — risky right before a competition ends if it breaks boot-critical hardware drivers); if the box fails to boot after a reboot, boot into Safe Mode and set this key back to7(disabled) or delete it.
Things to try / extra points#
Tip:
Set-ProcessMitigation -Systemchanges are broad and generally low-risk on a client workstation, making this a good "extra credit" action once the core checklist is done — but always test that required line-of-business software still launches afterward, especially older/legacy applications the README might call out.
Tip:
RunAsPPL(LSA Protection) requires a reboot to take effect, and on older builds/some drivers can cause compatibility issues — apply it, but budget time to verify the box still boots and logs in cleanly afterward before moving on.
Tip: WDigest, Safe DLL Search Mode, and Early Launch Antimalware policy are all CIS Level 1 controls that are easy to miss because they don't show up in a typical GUI walkthrough — they're registry-only settings. All three are low-risk to apply (no reboot required for the first two; Early Launch Antimalware policy takes effect on next boot).
16. BitLocker & Encryption#
BitLocker is less commonly a core scored item on client images than on the policy side (the Administrative Templates reference in Section 24 has a full BitLocker GPO block), but still worth checking:
- Control Panel → BitLocker Drive Encryption — check current status of all drives.
- If the README requires encryption on a specific drive, enable it: right-click the drive → Turn on BitLocker and follow the wizard (choose to save the recovery key somewhere accessible to you, e.g., a file on a USB stick provided by the competition, or print it — never leave it as the only unencrypted copy on the same drive if avoidable).
- If BitLocker is already on and the README doesn't call for it, do not disable it — decrypting can take a long time and provides no points; leave it alone unless specifically instructed.
Get-BitLockerVolume
manage-bde -status
manage-bde) listing each volume with its VolumeStatus (FullyDecrypted/FullyEncrypted/EncryptionInProgress) and ProtectionStatus (On/Off).Get-BitLockerVolumeis "not recognized" on Windows editions without BitLocker (e.g., Home edition) — BitLocker is a Pro/Enterprise/Education feature; check the edition withGet-ComputerInfo | Select WindowsProductNamebefore assuming it's missing/misconfigured.manage-bderequires an elevated prompt.
Tip: BitLocker Drive Encryption service should be at least Manual (see Services table) if BitLocker is or might be used — don't disable it if the README wants encryption enabled.
Tip: EFS (Encrypting File System) is a separate, file/folder-level encryption feature independent of BitLocker — if the README asks about "encrypted files," check
cipher /u /nto list EFS-encrypted files without changing anything.
cipher /u /n
cipher is normally used to wipe free disk space, but with these two flags it does something different: /u updates the user's EFS (Encrypting File System) key info, and /n tells it NOT to actually re-encrypt anything while doing so — combined, this just lists which files are EFS-encrypted without changing a single one.
/u /n = update user's key info without actually re-encrypting).- Returns nothing/empty if no EFS-encrypted files exist — that's a normal clean result, not an error.
- Must be run once per user profile you want to check (it only scans the currently-logged-on user's accessible files by default).
17. Internet Explorer / Edge / Browser Security#
Internet Explorer (legacy, still present on many images)#
- Open IE → Tools → Internet Options.
- General tab: set homepage to a neutral page (e.g.,
about:blankor a scenario-approved page — don't assumegoogle.comis always correct if the README specifies something else). - General → Browsing History → Settings: choose Never on the "Check for newer versions of stored pages" option, and enable Delete browsing history on exit.
- Security tab: raise the security level for each zone toward High.
- Privacy tab: raise to Block All Cookies (or the strictest level that doesn't break required functionality).
- Content tab: clear SSL state.
- Content → AutoComplete Settings: uncheck all boxes, then clear AutoComplete history and check Manage Passwords is empty.
- Apply, OK. Repeat similarly (best effort, exact steps vary) for any other installed browser (Chrome, Firefox, Edge).
Chrome / Firefox / Edge (Chromium) — Policy-Based Hardening#
- Prefer setting browser security via Group Policy ADMX templates / registry policy keys so settings can't be casually changed back through the UI, rather than only clicking through in-browser settings.
# Example: disable Firefox's built-in password manager via policy
New-Item -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox" -Name "OfferToSaveLogins" -Value 0 -Type DWord
about:preferences.- No error if Firefox isn't installed — the key is just created and does nothing.
- If Firefox is installed but the setting doesn't grey out, confirm the browser was fully closed (not just the window — check for a lingering
firefox.exeprocess) and relaunched; policy keys are read at startup.
Things to try / extra points#
Tip: Saved credentials/autofill data in any browser is a common scored item — check Settings → Passwords (Chrome/Edge) and about:logins (Firefox) and clear anything that shouldn't be stored, especially on a shared/kiosk-style scenario machine.
- Clear Windows' own saved credentials (Control Panel → User Accounts → Manage your credentials) — remove everything under both Windows Credentials and Web Credentials unless the README says a saved credential is required.
cmdkey /list
cmdkey /delete:<TargetName>
/list prints each stored credential's Target, Type, and User — /delete prints confirmation the target was removed./delete if you mistype the <TargetName> — copy it exactly (including any LegacyGeneric:target= prefix) from the /list output rather than retyping it by hand.Tip: Set each browser to auto-update if internet access allows — outdated browser versions are a common "missing updates" style vulnerability distinct from Windows Update itself.
18. Power Settings#
- Control Panel → System and Security → Power Options.
- Require a password on wakeup — enable this.
- Choose when to turn off the display / Change advanced power settings → set a reasonably short display/sleep timeout (e.g., 1–15 minutes, whatever the README/scenario expects) for both battery and plugged-in states.
- Save changes.
powercfg /query
powercfg /change monitor-timeout-ac 10
powercfg /change standby-timeout-ac 15
/query dumps the active power plan's full settings tree; the two /change commands are silent on success./change only affects the AC (plugged-in) profile by design here — on a laptop image, also run the -dc equivalents (monitor-timeout-dc, standby-timeout-dc) or the README/rubric may still flag battery-mode timeouts as unset. "Access is denied" means the prompt isn't elevated.Things to try / extra points#
Tip: "Require a password on wakeup" is a simple, high-confidence checkbox-style item — quick and reliable points, do it early.
19. Prohibited & Unauthorized Software / Files#
- Cross-check every installed program (Section 8) against the README's authorized list, with special attention to:
- Games (Steam, Minecraft, Solitaire/other bundled Windows games, emulators, ROMs)
- Hacking/pentesting tools (nmap, Wireshark, Metasploit, Cain & Abel, netcat, John the Ripper, Hydra, keyloggers, LOIC/HOIC, Aircrack-ng)
- P2P/torrent clients (uTorrent, BitTorrent, qBittorrent, Vuze, LimeWire, eMule)
- Cracks/keygens/pirated software indicators
- Unauthorized remote access tools (see Section 14)
- Media files in user profiles that violate an "acceptable use" style scenario rule (mp3/mp4/avi/etc. outside of anything explicitly authorized)
# Remove built-in/provisioned game & Xbox apps (adjust the match pattern to your scenario's definition of "unauthorized")
Get-AppxPackage -AllUsers | Where-Object { $_.Name -match "Xbox|Games|Zune|Solitaire" } |
Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -match "Xbox|Games|Zune|Solitaire" } |
Remove-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue
Get-AppxPackage -AllUsers | Where-Object Name -match "Xbox|Games|Zune|Solitaire" afterward should return nothing.- Some packages are protected system components that refuse removal even with
-AllUsers— that's expected for a few Xbox-identity packages tied to the OS itself; don't chase those further, they aren't "installed games" in the scored sense. - If nothing is removed at all, confirm you're running as an actual admin PowerShell window (AppX cmdlets silently no-op for non-admins more often than they error).
# Broad file sweep for prohibited media across all user profiles
Get-ChildItem -Path C:\Users -Recurse -Include *.mp3,*.mp4,*.avi,*.mkv,*.wav,*.wmv,*.mov -ErrorAction SilentlyContinue |
Select FullName, Length, LastWriteTime
- Can take a long time on a large disk — that's normal, not a hang; let it finish.
-Includeonly works reliably here because-Recurseis present; if you add a-Pathwithout a trailing wildcard behavior changes on older PowerShell versions — test on a small folder first if results look wrong.- Files in
AppDataor Windows-owned media (sample music/videos) will show up too; cross-reference against the README before deleting anything — don't nuke default Windows sample media as if it were user-added contraband.
- Windows Copilot / Widgets / Cortana — three newer consumer-shell features that ship enabled by default on current Windows 11 images and are explicitly CIS Level 1 "should be Disabled" items. None of these are malware, but each is an unauthorized-software-adjacent attack surface (cloud AI assistant with system access, a widgets panel that pulls remote content, a voice assistant with microphone access) that a strict scenario is likely to flag:
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" -Name "TurnOffWindowsCopilot" -Value 1 -Type DWord
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
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name "AllowCortana" -Value 0 -Type DWord
Stop-Process -Name explorer -Force then let it relaunch, or just reboot).- "Cannot find path" on the last line if
Windows Searchkey doesn't exist yet — addNew-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Forcebefore it. - These features don't exist at all pre-Windows 11 (Copilot) or on older Windows 10 builds (Widgets) — "not recognized"/no visible change on those images is expected, not a failure, just skip this block.
Things to try / extra points#
Tip: Before deleting any flagged file, double check it isn't referenced by a forensics question ("what is the name of the largest media file on this system?") — screenshot/record first, delete second.
Tip: Renamed file extensions are a known trick (
virus.exerenamed tovirus.jpg.exeorvirus.txt) — when in doubt, check actual file type/magic bytes rather than trusting the extension:
Get-Item "C:\path\to\suspicious.jpg" | Select Name, Extension, Length
# Or open in a hex-capable tool / check file signature bytes manually if truly suspicious
- No error mode.
- To actually check magic bytes without a hex editor,
Format-Hex "C:\path\to\suspicious.jpg" -Count 16in PowerShell 5.1+ shows the first bytes — an EXE starts with4D 5A("MZ"), a real JPEG starts withFF D8 FF; a mismatch is the actual proof of a renamed/disguised file.
- Disable Autorun/AutoPlay globally — a classic vector for "prohibited/malicious content auto-launching from removable media":
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "NoAutoplayfornonVolume" -Value 1 -Type DWord
- No common error beyond permissions/missing path (fixed by
-ForceonNew-Item, already included). 255(0xFF) disables Autorun on all drive types; if a required scenario workflow depends on Autorun for a specific approved drive type, that's a real conflict — check the README before applying blanket lockdown.
20. Windows Features (Add/Remove Components)#
GUI Method#
- Control Panel → Programs and Features → Turn Windows features on or off (or
optionalfeatures.exedirectly). - Disable (unless required by README):
- Games
- Internet Information Services (IIS) and IIS Hostable Web Core
- Media Features (if scenario disallows media playback)
- Print and Document Services (unless printing required)
- SNMP
- Telnet Client / Telnet Server
- TFTP Client
- XPS Services / XPS Viewer
- Be careful with Windows PowerShell — the historical source checklist lists it as something to disable, but doing so removes your own ability to run most commands in this document. Only disable PowerShell if the README explicitly requires it and you're finished using it, or use PowerShell 2.0-engine-removal-style hardening (removing the legacy v2 engine,
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2) instead of removing PowerShell entirely.
Command-Line Method#
Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq "Enabled" } | Select FeatureName
Disable-WindowsOptionalFeature -Online -FeatureName TelnetClient, TFTP, PeerToPeer -NoRestart
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2, MicrosoftWindowsPowerShellV2Root -NoRestart
Get- line lists every currently-enabled optional feature by name; each Disable- call reports RestartNeeded : True/False (with -NoRestart you defer the actual reboot).- "The feature name X is unknown" if a listed feature isn't present on this SKU/build — not every feature exists on every Windows edition; drop the missing name from the list and re-run with the rest.
- Disabling
SMB1Protocolcan break connectivity to very old file shares/printers that still require SMBv1 — check the README/network requirements before disabling if the scenario mentions legacy shared devices. - Changes queue until the next reboot; nothing takes effect until you restart.
Things to try / extra points#
Tip: If
World Wide Web Publishing Serviceshows up running (see Services), that means IIS is installed — treat it the same as any other unauthorized server role on a client workstation and disable the feature entirely unless the README specifically calls for a web server role.
Tip: Removable-media/USB storage can be blocked entirely at the driver level if the scenario calls for locking down physical data-exfiltration vectors:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\USBSTOR" -Name "Start" -Value 4 -Type DWord
Value
4disables the USB mass-storage driver from starting;3restores default (manual start, i.e. normal USB drive functionality). Don't apply this if the competition needs you to transfer files via USB.
- "Access is denied" without elevation.
- If you accidentally lock yourself out of a USB drive you need (e.g., the scoring engine/README delivered via USB), set the value back to
3and unplug/replug the drive — no reboot required to restore access.
21. Scheduled Tasks#
GUI Method#
- Open
taskschd.msc(Task Scheduler). - Browse the Task Scheduler Library, expanding all folders (don't just check the root).
- Review every non-Microsoft task, and any Microsoft-path task that looks off (unexpected trigger, unexpected action/binary). Disable or delete unauthorized tasks.
Command-Line Method#
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" } | Select TaskName, TaskPath, State
# Focus on non-Microsoft tasks specifically — these are far more likely to be planted
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" -and $_.TaskPath -notlike "\Microsoft*" } |
Select-Object TaskName, TaskPath
Get-ScheduledTask is "not recognized" on PowerShell 2.0/very old images — fall back entirely to the schtasks command below, which works on every Windows version back to XP.schtasks /query /fo LIST /v
more (schtasks /query /fo LIST /v | more) or redirect to a file (schtasks /query /fo LIST /v > tasks.txt) if it scrolls past what you can review on screen.Things to try / extra points#
Tip: Malicious scheduled tasks are one of the most common persistence mechanisms used in vulnerable CyberPatriot images — always check the task's Actions tab for what program/script it actually runs, not just its name (a task can be named "Adobe Update Check" and run something else entirely).
Get-ScheduledTask -TaskName "SuspiciousTaskName" | Select -ExpandProperty Actions
Execute (program/script path) and Arguments fields — this is the ground truth of what the task actually does, regardless of its display name.TaskName from the earlier Get-ScheduledTask output rather than retyping.- To disable a confirmed-bad task without breaking a required trigger pattern you might want to reference later, disable it rather than deleting outright (mirrors the "disable, don't delete" philosophy from account management):
Disable-ScheduledTask -TaskName "SuspiciousTaskName" -TaskPath "\"
State : Disabled.-TaskPath doesn't match — -TaskPath must match the task's folder exactly (root is "\", but subfolder tasks need e.g. "\Microsoft\Windows\SomeFolder\" with both leading and trailing backslashes); get the exact value from the TaskPath column in the earlier query rather than guessing.22. Registry Autoruns & Hidden Persistence#
Beyond msconfig/Task Manager Startup entries (Section 10), several registry locations are classic malware persistence points that the GUI startup tools do not show.
Image File Execution Options (IFEO) "Sticky Keys" Hijack#
A famous technique: redirect the debugger for an accessibility tool (sethc.exe, utilman.exe, osk.exe, magnify.exe, narrator.exe, displayswitch.exe) to cmd.exe, giving SYSTEM-level shell access from the logon screen.
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*" -ErrorAction SilentlyContinue |
Select-Object PSChildName, Debugger
Debugger value populated) — IFEO subkeys legitimately exist for things like Visual Studio JIT debugging, but a Debugger value pointing at a shell is the red flag, not the mere existence of IFEO entries.- No error mode.
- Don't panic at IFEO subkeys for unrelated apps (some legitimate software uses IFEO for compatibility shims) — only act on entries where
PSChildNameis an accessibility tool (sethc.exe,utilman.exe, etc.) with aDebuggervalue set at all.
- If any
Debuggervalue points tocmd.exe,powershell.exe, or anything other than the tool's own expected behavior, delete that Debugger value/key immediately. Expected result:Remove-ItemProperty -Path "HKLM:\SOFTWARE\...\Image File Execution Options\sethc.exe" -Name "Debugger"(or delete the whole subkey withRemove-Item) — silent on success. If it fails: "Access is denied" without elevation. After removal, test by pressing Shift 5 times at the logon screen (not while logged in) to confirm Sticky Keys launches normally instead of a command prompt.
Winlogon Shell/Userinit Hijack#
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" | Select-Object Shell, Userinit
Shell : explorer.exe and Userinit : C:\Windows\system32\userinit.exe,.- No error mode.
- To fix a hijacked value:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "Shell" -Value "explorer.exe"(and similarly forUserinit, remembering the trailing comma) — takes effect on next logon, so log off/on or reboot to confirm the fix actually stuck rather than trusting the registry read alone.
- Expected defaults:
Shell = explorer.exe,Userinit = C:\Windows\system32\userinit.exe,(note the trailing comma is normal). Anything else appended or substituted is a persistence/hijack indicator — restore the defaults.
AppInit_DLLs / AppCertDlls (DLL Injection)#
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -Name "AppInit_DLLs" -ErrorAction SilentlyContinue
Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Session Manager\AppCertDlls" -ErrorAction SilentlyContinue
AppInit_DLLs string value (or the property/key absent entirely) on a clean machine; AppCertDlls key is normally absent altogether.- These should normally be empty/absent. If populated with an unfamiliar DLL path, that DLL is being force-loaded into every process (or every process calling CreateProcess, for AppCertDlls) — investigate and clear it:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" -Name "LoadAppInit_DLLs" -Value 0 -Type DWord
- "Cannot find path" on the WOW6432Node line on a genuine 32-bit OS — that registry view doesn't exist there; skip that line and run only the native path.
- To fully remediate a populated
AppInit_DLLsvalue, also clear the DLL path itself:Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -Name "AppInit_DLLs" -Value "".
Admin-Tool Sabotage via Policy Registry Keys#
A recurring, low-tech CyberPatriot technique: the scenario (or a "malicious insider") disables Task Manager, cmd.exe, or Control Panel for the current user via raw registry policy keys — without a corresponding Group Policy Object, so it won't show up when you check gpresult. This matters because a locked Task Manager or cmd.exe is usually hiding a bigger problem: if you can't open Task Manager, you can't see the malicious process; if cmd.exe is blocked, some of your own remediation commands may silently fail.
# 1. Check the three classic "lock the admin out of their own tools" keys
Get-ItemProperty "HKCU:\Software\Policies\Microsoft\Windows\System" -Name "DisableCMD" -ErrorAction SilentlyContinue
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableTaskMgr" -ErrorAction SilentlyContinue
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoControlPanel" -ErrorAction SilentlyContinue
1/2 means that tool is sabotaged for this user.- If any of these keys exist and are set to
1(or2forDisableCMD, which also blocks.bat/.cmdscripts), that tool has been deliberately sabotaged for the current user. Remove or zero them out:
# 2. Remove/zero each one that was found set
Remove-ItemProperty -Path "HKCU:\Software\Policies\Microsoft\Windows\System" -Name "DisableCMD" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableTaskMgr" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoControlPanel" -ErrorAction SilentlyContinue
cmd.exe restrictions to fully clear.cmd.exe itself is what's blocked (DisableCMD = 2) you may not be able to run this PowerShell block from a blocked cmd.exe window at all — run it from a PowerShell window instead (PowerShell isn't affected by DisableCMD), or via Task Manager's "Run new task" if Task Manager itself is still accessible.- These are per-user (
HKCU) keys, so if there are multiple user profiles on the box, repeat the check for each one by loading their hive (reg load) or checkingHKEY_USERS\<SID>\...instead of just your own logged-in profile'sHKCU.
WMI Event Subscriptions (Fileless Persistence)#
Get-CimInstance -Namespace root\subscription -ClassName __EventConsumer
Get-CimInstance -Namespace root\subscription -ClassName __EventFilter
Get-CimInstance -Namespace root\subscription -ClassName __FilterToConsumerBinding
This checks for a fileless persistence trick: WMI (Windows Management Instrumentation) can be configured to automatically run a command whenever some condition is met (e.g., "every time a process named X starts") — with no file ever written to disk and no entry in the normal Startup/Task Scheduler lists. __EventFilter defines the trigger condition, __EventConsumer defines what runs, and __FilterToConsumerBinding links the two together — malware sets up all three, so all three need checking.
- Empty output on a clean machine (these classes normally have zero instances).
- Any returned object — especially a
CommandLineEventConsumerwith a suspiciousCommandLineTemplate— is a real persistence finding.
- "Invalid namespace" is very unusual (this namespace exists on all modern Windows) — more likely just genuinely empty results, which is the expected clean state.
- To remove a confirmed-malicious binding, delete in this order — binding first, then filter and consumer — via
Get-CimInstance ... | Remove-CimInstance, since removing the filter/consumer first can leave an orphaned binding reference.
- These allow malware to execute on a trigger (e.g., "every time a process named X starts") without any file or Run-key ever appearing — this is an advanced technique but worth a quick look on a harder image or if a forensics question hints at "no obvious startup entry found."
Things to try / extra points#
Tip: This class of persistence (IFEO, Winlogon, AppInit_DLLs, WMI subscriptions) is rare in beginner-level CyberPatriot images but shows up more in advanced/high-scoring rounds. If your team has already done the "obvious" checklist items and the score seems capped, this section is where to look next.
Tip: Environment variables can also be abused for persistence/injection — a quick sanity check:
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Path, TEMP, windir, etc.) with expected values — Path should contain only legitimate system/application directories.- No error mode.
- A
Pathentry pointing at an unusual writable user-owned folder (e.g., something underAppDataorC:\Users\Public) is the actual red flag — that folder could contain a malicious binary shadowing a legitimate command name via search-order hijacking.
- Reset system folder permissions if you suspect a rootkit modified ACLs on core Windows directories (use cautiously — this is a broad, slow operation):
icacls "C:\Windows\System32" /reset /T /C /Q
/reset resets permissions back to their inherited defaults. /T applies it recursively through every subfolder. /C tells it to keep going even if it hits an error on an individual locked file, instead of stopping the whole operation. /Q suppresses the normal per-file success messages so you just get a final summary instead of a huge scroll of text.
- This is a heavy, disruptive operation — resetting inherited ACLs on the entire System32 tree can break third-party security software or drivers that legitimately customized permissions there; only run this if you have specific, strong evidence of ACL tampering (not as a routine step), and be prepared that it may require a reboot afterward if the system behaves oddly.
/Ccontinues past individual access-denied errors on locked system files rather than aborting — some "failed" lines for in-use files during the run are normal and expected, not a sign the whole operation failed.
23. Event Log Review & Audit Logging#
GUI Method#
- Open
eventvwr.msc. - Review Windows Logs → Security for logon failures (Event ID 4625), new user creation (4720), account enabled/disabled (4722/4725), group membership changes (4728/4732/4756), and any other anomalies relevant to forensics questions.
- Review Windows Logs → System and Application for service failures, driver issues, or crash patterns.
- Increase log size / set retention so logs aren't silently overwritten before you can review them (Properties on each log → increase Maximum log size, set "Overwrite events as needed" or "Archive the log when full").
Command-Line Method#
Get-WinEvent -LogName Security -MaxEvents 100 | Select TimeCreated, Id, Message
# Failed logons specifically
Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4625]]" -MaxEvents 50
# New local user created
Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4720]]" -MaxEvents 50
- "No events were found that match the specified selection criteria" for the filtered queries just means zero matching events exist (e.g., no failed logons yet) — that's a valid clean result, not an error. "Attempted to perform an unauthorized operation" means the Security log requires an elevated PowerShell session to read even for viewing.
- If the Security log's audit policy hasn't been configured (see next block), event ID 4720/4625 may simply never have been logged in the first place regardless of query correctness.
Enabling Full Auditing (also covered in Section 5, repeated here for context)#
auditpol /set /category:* /success:enable /failure:enable
The command was successfully executed.- "Access is denied" without an elevated prompt.
- Enabling every category at max verbosity generates a LOT of log volume — combined with the log-size increase noted below, otherwise logs will rotate/overwrite fast and you'll lose the very evidence you just started collecting.
PowerShell Script-Block Logging (advanced/extra credit)#
Set-ExecutionPolicy -ExecutionPolicy Restricted -Scope LocalMachine -Force
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
Microsoft-Windows-PowerShell/Operational event log (Event ID 4104) for any script run afterward.Set-ExecutionPolicy Restricted breaks your own future .ps1 script execution for the rest of the round; if that happens and you need scripts working again, run Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force to loosen it back up.Caution: Setting the PowerShell execution policy to
Restrictedwill block your own future.ps1scripts from running (though inline commands typed directly into the console still work). If you plan to keep using PowerShell scripts during the round, useRemoteSignedinstead, or applyRestrictedonly as your very last step before moving on.
Things to try / extra points#
Tip: Never clear the event logs to "clean things up" — that destroys forensic evidence you may still need for scoring questions, and log-tampering itself is sometimes a scored/penalized action.
Tip:
wevtutil qe Security /c:1 /rd:true /f:text(or theGet-WinEventequivalents above) let you pull specific recent entries fast without opening the heavier Event Viewer GUI — useful under time pressure.
CIS Benchmark cross-reference: CIS Level 1 recommends sizing the four core Event Logs well beyond Windows' small defaults — commonly cited figures are roughly 32,768 KB or larger for the Application, Setup, and System logs, and a much larger 196,608 KB or larger for the Security log specifically (it fills up fastest once full auditing is on). If you're not certain of the exact current CIS figure, erring generously large is safe and low-risk — the goal is simply "don't silently lose evidence to log rotation."
24. Group Policy / secpol.msc / Administrative Templates Reference#
Use gpedit.msc (Local Group Policy Editor — not available on Home editions) for Administrative Templates, and secpol.msc for the Account Policies / Local Policies items already covered in Sections 4–6. Add snap-ins via mmc.exe → File → Add/Remove Snap-in if the direct .msc shortcuts aren't available on your edition.
Do this section last. As the original source material warns: these Administrative Template changes can be extremely restrictive and, in aggregate, may limit your own ability to keep working on the box (disabled Control Panel pages, locked toolbars, blocked installers, etc.). Make sure every other section is done first.
Commonly-Tested / High-Yield Administrative Template Settings#
Based on general CyberPatriot community experience, these categories come up often enough to prioritize within the huge Administrative Templates tree. Many of them are also explicit CIS Microsoft Windows 10/11 Benchmark, Level 1 controls, noted below where that's the case — Level 1 means "broad-compatibility hardening," generally safe to apply on a competition image without breaking required functionality.
| Category | Setting | Recommended Value |
|---|---|---|
| Windows Components → AutoPlay Policies | Turn off Autoplay | Enabled (All Drives) — CIS Level 1 |
| Windows Components → AutoPlay Policies | Turn off Autoplay for non-volume devices | Enabled — CIS Level 1 |
| Windows Components → Windows Update | Configure Automatic Updates | Enabled, "Auto download and schedule the install" |
| Windows Components → Windows Defender | Turn off Windows Defender | Disabled (i.e., do NOT turn it off) |
| Windows Components → Windows Defender | Turn off real-time protection | Disabled (i.e., keep real-time protection ON) — CIS Level 1 |
| Windows Components → Remote Desktop Services | Allow users to connect remotely using RDS | Disabled (unless required) |
| Windows Components → Windows Installer | Disable Windows Installer | Disabled (leave installer enabled unless scenario says otherwise) |
| Windows Components → Windows Installer | Always install with elevated privileges | Disabled — CIS Level 1, see Section 12 |
| System → Removable Storage Access | All removable storage classes: Deny all access | Enabled (only if the scenario wants removable media blocked entirely) |
| System → Device Installation Restrictions | Prevent installation of removable devices | Enabled (same caveat as above) |
| System → Logon | Do not process the legacy run list | Enabled |
| System → Logon | Do not display network selection UI | Enabled — CIS Level 1 (stops selecting/changing Wi-Fi networks from the lock screen without logging in) |
| System → User Profiles | Turn off the advertising ID | Enabled — CIS Level 1 |
| Network → Network Connections → Windows Firewall | Protect all network connections | Enabled |
| Network → Lanman Server | Hash publication for BranchCache | Disabled |
| Network → Lanman Workstation | Enable insecure guest logons | Disabled — CIS Level 1, see Section 13 |
| Network → Network Provider | Hardened UNC Paths (require mutual authentication and integrity for \\*\NETLOGON and \\*\SYSVOL) |
Enabled — CIS Level 1 (most relevant on domain-joined machines; low-risk to set regardless) |
| Network → Microsoft Peer-to-Peer Networking | Turn off Microsoft Peer-to-Peer networking services | Enabled |
| Windows Components → Internet Explorer | Turn off InPrivate Browsing | Enabled (if scenario disallows private browsing) |
| Windows Components → Event Log Service | Max log size / Retain old events | Sized generously; retain events on — see Section 23 for CIS-cited size figures |
| Windows Components → Windows Update | Do not display "install updates and shut down" | Enabled |
| Windows Components → Cloud Content | Turn off Microsoft consumer experiences | Enabled — CIS Level 1 |
| Windows Components → Data Collection and Preview Builds | Allow Telemetry | Enabled, lowest available level (e.g. "Security" or "Basic" depending on edition) — CIS Level 1 |
| Control Panel → Personalization | Prevent enabling lock screen camera / Prevent enabling lock screen slide show | Enabled — CIS Level 1 |
Treat this curated table as a starting point, not an exhaustive guarantee — CyberPatriot does not publish an official scoring rubric, so "commonly tested" here is drawn from general community experience with these categories historically appearing across many practice/competition images, not a promise about any specific round. The CIS Level 1 annotations are based on well-established, widely-cited CIS Windows Benchmark categories; exact setting names/paths can shift slightly between Windows 10 and 11 builds, so verify the live control in
gpedit.mscmatches the description if it looks off.
CIS Level 2 — Defense-in-Depth (Worth Trying If Time Permits)#
CIS Level 2 controls are stricter than Level 1 and are meant for higher-security environments — they carry more risk of breaking legitimate functionality (remote administration tooling, cross-device features, peripherals), so apply them only after the rest of this document is done and you've confirmed they don't conflict with anything the README requires.
| Category | Setting | Recommended Value |
|---|---|---|
| System → Remote Procedure Call | Restrict Unauthenticated RPC clients | Enabled, Authenticated |
| System → Remote Procedure Call | RPC Endpoint Mapper Client Authentication | Enabled |
| System → OS Policies | Allow Clipboard synchronization across devices | Disabled |
| System → OS Policies | Allow upload of User Activities | Disabled |
| Windows Components → Camera | Allow use of Camera | Disabled |
| Local Security Policy → Security Options | Network access: Restrict clients allowed to make remote calls to SAM | Administrators (see Section 6) |
These are genuinely optional "extra credit" — a CyberPatriot image can score well without any of them, and a few (Clipboard sync, RPC restrictions) have real potential to interfere with a scenario that expects those features to work. Test after applying, don't just set-and-forget.
Full Administrative Templates Reference (from historical checklist source)#
The table below is preserved from the original "Ultimate Windows Checklist" GPO reference for completeness. It is organized by the same category structure as gpedit.msc. Treat "Not configured" values as leave alone / lowest priority — they represent the source checklist's judgment that the setting didn't need to deviate from default. This is the exhaustive appendix; work through the rest of this document first, then use this if you have time remaining and want to squeeze out additional hardening.
Control Panel
| Setting | Value |
|---|---|
| Regional and Language Options → Restrict the UI languages Windows uses | Enabled – English |
| Regional and Language Options → Force selected system UI language to override User UI language | Disabled |
| User Accounts → Apply the default user logon picture to all users | Enabled |
Network — BITS
| Setting | Value |
|---|---|
| Do not allow the BITS client to use Windows Branch Cache | Enabled |
| Do not allow the computer to act as a BITS peer-caching client | Enabled |
| Do not allow the computer to act as a BITS peer-caching server | Enabled |
| Allow BITS peer-caching | Disabled |
| Time-out for inactive BITS jobs | Enabled, 1 Day |
| Limit the maximum network bandwidth for BITS background transfers | Enabled, 0 |
| Limit the maximum network bandwidth | Enabled, 1 |
| Limit the BITS peer-cache size | Enabled, 1 |
| Limit the age of files in the BITS peer-cache | Enabled, 1 |
| Limit the maximum BITS job download time | Enabled, 1 |
| Limit the maximum number of files in a BITS job | Enabled, 1 |
| Limit the maximum number of BITS jobs for this computer | Enabled, 1 |
| Limit the maximum number of BITS jobs per user | Enabled, 1 |
| Limit the maximum number of ranges per file in a BITS job | Enabled, 1 |
Network — Branch Cache
| Setting | Value |
|---|---|
| Turn on BranchCache | Disabled |
| Set BranchCache Distributed Cache mode | Disabled |
| Set BranchCache Hosted Cache mode | Disabled |
| Configure BranchCache for network files | Disabled |
| Set percentage of disk space used for client computer cache | Enabled, 1 |
Network — DNS Client
| Setting | Value |
|---|---|
| Allow DNS suffix appending to unqualified multi-label name queries | Disabled |
| Dynamic Update | Enabled |
| Registration Refresh Interval | Enabled, 1000 |
| TTL set in the A and PTR record | Enabled, 300 |
| Update Security Level / Update Top Level Domain Zones | Enabled |
| Primary DNS Suffix Devolution | Enabled |
| Turn off Multicast Name Resolution (LLMNR) | Enabled |
Network — Lanman Server / Link-Layer Topology Discovery / Peer-to-Peer
| Setting | Value |
|---|---|
| Hash publication for BranchCache | Disabled |
| Disable password strength validation for Peer Grouping | Disabled |
| Turn off Microsoft Peer-to-Peer networking services | Enabled |
| PNRP Clouds (Global/Link-Local/Site-Local) — Turn off Multicast Bootstrap | Enabled |
| PNRP Clouds — Turn off PNRP cloud creation | Enabled |
| PNRP Clouds — Set PNRP cloud to resolve only | Enabled |
Network — Network Connections (Windows Firewall legacy policy)
| Setting | Value (Domain & Standard Profiles) |
|---|---|
| Protect all network connections | Enabled |
| Allow inbound file and printer sharing exception | Disabled |
| Allow logging | Enabled |
| Prohibit notifications | Disabled |
| Allow inbound remote administration exception | Disabled |
| Allow inbound UPnP framework exception | Disabled |
| Windows Firewall: Allow authenticated IPsec bypass | Disabled |
| Prohibit installation/configuration of Network Bridge | Disabled |
| Prohibit use of Internet Connection Firewall on DNS domain network | Disabled |
| Prohibit use of Internet Connection Sharing on DNS domain network | Enabled |
| Require domain users to elevate when setting a network's location | Enabled |
Network — Offline Files
| Setting | Value |
|---|---|
| Sub-folders always available offline | Disabled |
| Administratively assigned offline files | Disabled |
| Limit disk space used by Offline Files | Enabled, 1, 1 |
| Allow or disallow use of the Offline Files feature | Disabled |
| Encrypt the Offline Files cache | Enabled |
| Event logging level | Enabled, 3 |
| Prevent use of Offline Files folder | Enabled |
| Remove "Make Available Offline" | Enabled |
| Prohibit "Make Available Offline" for these file/folders | Enabled |
| Turn off reminder balloons | Enabled |
| Enable transparent caching | Disabled |
| At logoff, delete local copy of user's offline files | Enabled |
| Turn on economical application of admin-assigned Offline Files | Disabled |
| Reminder balloon frequency / initial lifetime / lifetime | Disabled |
| Synchronize all offline files before logging off / on / before suspend | Disabled |
Network — SNMP / SSL / TCP-IP / Windows Connect Now
| Setting | Value |
|---|---|
| SNMP Communities | Disabled |
| SNMP Permitted Managers | Disabled |
| SNMP Traps for public community | Disabled |
| SSL Cipher Suite Order | Disabled |
| Prohibit access of the Windows Connect Now wizards | Enabled |
Network — Printers
| Setting | Value |
|---|---|
| Allow Print Spooler to accept client connections | Disabled |
| Allow printers to be published | Disabled |
| Allow pruning of published printers | Disabled |
| Always render print jobs on the server | Disabled |
| Automatically publish new printers in AD | Disabled |
| Computer location | Enabled |
| Custom support URL in Printers folder | Disabled |
| Disallow installation of printers using kernel-mode drivers | Enabled |
| Execute print drivers in isolated processes | Disabled |
| Log directory pruning retry events | Enabled |
| Only use Package Point and Print | Enabled |
| Override print driver execution compatibility setting | Enabled |
| Pre-populate printer search location text | Disabled |
| Printer browsing | Disabled |
| Prune printers not automatically republished | Disabled |
| Web-based printing | Disabled |
System — Credentials Delegation
| Setting | Value |
|---|---|
| Allow delegating default/fresh/saved credentials (all variants) | Disabled |
| Allow delegating credentials with NTLM-only server authentication (all variants) | Disabled |
| Deny delegating default/fresh/saved credentials | Enabled |
System — Device Installation
| Setting | Value |
|---|---|
| Allow admins to override Device Installation Restriction policies | Enabled |
| Allow installation of devices matching any of these device IDs | Disabled |
| Allow installation of devices using drivers matching these classes | Disabled |
| Prevent installation of devices not described by other policy settings | Enabled |
| Prevent installation of removable devices | Enabled |
| Allow remote access to the PnP interface | Disabled |
| Configure device installation timeout | Enabled, 300 |
| Do not send a Windows error report on generic driver installation failure | Enabled |
| Prevent creation of a system restore point during device activity | Enabled |
| Prevent device metadata retrieval from the Internet | Enabled |
| Prioritize all digitally signed drivers equally | Enabled |
| Turn off "found new hardware" balloons during device installation | Enabled |
| Prevent redirection of USB devices | Enabled |
System — Disk NV Cache / Disk Quotas
| Setting | Value |
|---|---|
| Turn off Boot and Resume Optimizations | Enabled |
| Turn off Cache Power Mode | Enabled |
| Turn off Non-volatile Cache Feature | Enabled |
| Turn off solid state mode | Enabled |
| Apply policy to removable media (Disk Quotas) | Enabled |
| Enable disk quotas | Enabled |
| Log event when quota limit / warning level exceeded | Enabled |
System — Distributed COM / Driver Installation / Enhanced Storage
| Setting | Value |
|---|---|
| Allow local activation security check exemptions | Disabled |
| Define Activation Security Check exemptions | Disabled |
| Allow non-admins to install drivers for these device setup classes | Disabled |
| Allow Enhanced Storage certificate provisioning | Enabled |
| Allow only USB root hub connected Enhanced Storage devices | Disabled |
| Do not allow non-Enhanced Storage removable devices | Enabled |
| Lock Enhanced Storage when the computer is locked | Enabled |
System — File System / Group Policy Processing
| Setting | Value |
|---|---|
| Do not allow compression on all NTFS volumes | Enabled |
| Enable NTFS pagefile encryption | Enabled |
| Disable delete notifications on all volumes | Enabled |
| Selectively allow the evaluation of a symbolic link | Disabled |
| Allow cross-forest user policy and roaming user profiles | Disabled |
| Always use local ADM files for Group Policy Object Editor | Disabled |
| Disallow interactive users from generating RSOP data | Enabled |
| Group Policy refresh interval for computers/domain controllers | Enabled, 180 min / 20 min offset |
| Remove users' ability to invoke machine policy refresh | Enabled |
| Turn off background refresh of Group Policy | Disabled |
| Turn off RSOP logging | Disabled |
System — Internet Communication Management
| Setting | Value |
|---|---|
| Turn off downloading of print drivers over HTTP | Enabled |
| Turn off Event Viewer "Events.asp" links | Enabled |
| Turn off handwriting personalization data sharing | Enabled |
| Turn off handwriting recognition error reporting | Enabled |
| Turn off Internet Connection Wizard if URL referring to Microsoft | Enabled |
| Turn off Internet download for web publishing/online ordering wizards | Enabled |
| Turn off Internet File Association service | Enabled |
| Turn off printing over HTTP | Enabled |
| Turn off Registration if URL referring to Microsoft | Enabled |
| Turn off Search Companion content file updates | Enabled |
| Turn off "Order Prints" picture task | Enabled |
| Turn off "Publish to Web" task | Enabled |
| Turn off Windows Messenger customer experience | Enabled |
| Turn off Windows Error Reporting | Enabled |
| Turn off Windows Update device driver searching | Disabled |
System — iSCSI / Kerberos / Locale Services
| Setting | Value |
|---|---|
| Do not allow additional session logins | Enabled |
| Do not allow changes to initiator IQN name | Enabled |
| Do not allow changes to initiator CHAP secret | Enabled |
| Do not allow connections without IPsec | Enabled |
| Do not allow sessions without mutual/one-way CHAP | Enabled |
| Do not allow manual configuration of iSCSI targets/portals/iSNS | Enabled |
| Require strict KDC validation | Enabled |
| Require strict target SPN match on RPC | Enabled |
| Use forest search order | Enabled |
| Disallow changing of geographic location | Enabled |
| Disallow selection of custom locales | Enabled |
| Disallow user override of locale settings | Enabled |
| Restrict system/user locales | Enabled, en-US |
System — Logon / Power Management
| Setting | Value |
|---|---|
| Always use classic logon | Enabled |
| Do not process the legacy run list | Enabled |
| Do not process the run-once list | Enabled |
| Don't display the "Getting Started" welcome screen at logon | Enabled |
| Hide entry points for Fast User Switching | Enabled |
| Run these programs at user logon | Disabled |
| Turn off Windows Startup Sound | Enabled |
| Turn off the hard disk (on battery / plugged in) | Enabled, 150 |
| Require a password when a computer wakes (on battery / plugged in) | Enabled |
| Specify the System Hibernate/Sleep/Unattended Sleep Timeout | Enabled, 450–600 |
| Reduce Display Brightness / Specify Display Dim Brightness | Enabled, 180 |
| Turn off Adaptive Display Timeout | Enabled, 240 |
| Turn off the display (on battery / plugged in) | Enabled, 300 |
| Allow restore of system to default state (Recovery) | Enabled |
System — Remote Assistance / RPC / Removable Storage / Scripts
| Setting | Value |
|---|---|
| Configure Offer Remote Assistance | Disabled |
| Configure Solicited Remote Assistance | Disabled |
| Turn on session logging (Remote Assistance) | Enabled |
| Restrictions for Unauthenticated RPC clients | Enabled, Authenticated without exceptions |
| RPC Endpoint Mapper Client Authentication | Enabled |
| Removable storage classes — deny all access | Not configured by default (Enable if scenario requires locking down removable media) |
| Allow logon scripts when NetBIOS/WINS disabled | Disabled |
| Run startup scripts visible | Enabled |
| Turn off System Restore | Disabled (i.e., leave System Restore ON) |
System — Troubleshooting, User Profiles, Windows File Protection
| Setting | Value |
|---|---|
| Notify blocked drivers | Enabled |
| Detect application failures caused by deprecated COM/Windows components | Enabled, All |
| MSDT: Turn on interactive communication with Support | Disabled |
| MSDT: Restrict tool download | Enabled |
| Add the administrators security group to roaming user profiles | Enabled |
| Delete user profiles older than a specified number of days | Enabled, 29 |
| Delete cached copies of roaming profiles | Enabled |
| Only allow local user profiles | Enabled |
| Do not log users on with temporary profiles | Enabled |
| Hide the file scan progress window (WFP) | Disabled |
| Limit Windows File Protection cache size | Enabled, 50 |
Windows Components — AutoPlay, Backup, Biometrics
| Setting | Value |
|---|---|
| Turn off Autoplay | Enabled |
| Turn off Autoplay for non-volume devices | Enabled |
| Prevent backing up to local disks/network location/optical media | Enabled |
| Turn off the ability to back up data files / create a system image | Enabled |
| Allow domain users to log on using biometrics | Disabled |
| Allow the use of biometrics | Disabled |
Windows Components — BitLocker Drive Encryption
| Setting | Value |
|---|---|
| Fixed/Removable/OS Drives — most sub-settings | Not configured by default; configure per README if BitLocker is in scope |
| Choose drive encryption method and cipher strength | Not configured by default; set explicitly if BitLocker required |
| Store BitLocker recovery info in Active Directory | Not configured (domain-only) |
Windows Components — Credential UI, Desktop Gadgets, DWM
| Setting | Value |
|---|---|
| Enumerate administrator accounts on elevation | Disabled |
| Require trusted path for credential entry | Enabled |
| Turn off desktop gadgets | Enabled |
| Turn off user-installed desktop gadgets | Enabled |
| Do not allow color changes / desktop composition / Flip3D / window animations (DWM) | Enabled (disable these effects) |
Windows Components — Event Log Service
| Log | Setting | Value |
|---|---|---|
| Application / Security / Setup / System | Backup log automatically when full | Enabled |
| Application / Security / Setup / System | Max Log Size | Enabled, 2046 (KB) or larger |
| Application / Security / Setup / System | Retain old events | Enabled |
Windows Components — Game Explorer / HomeGroup
| Setting | Value |
|---|---|
| Turn off downloading of game information | Enabled |
| Turn off game updates | Enabled |
| Turn off tracking of last play time | Enabled |
| Prevent the computer from joining a HomeGroup | Enabled |
Windows Components — Internet Explorer (selected high-value entries)
| Setting | Value |
|---|---|
| Turn off Accelerators | Enabled |
| Turn off Compatibility View / Compatibility View button | Enabled |
| Prevent deleting cookies/passwords/temp files/history (Delete Browsing History) | Enabled (i.e., admin-locks the delete-history controls) |
| Security Zones: Use only machine settings | Enabled |
| Security Zones: Do not allow users to add/change sites or policies | Enabled |
| Turn on Warn about certificate address mismatch | Enabled |
| Disable the Advanced/Connections/Content/General/Privacy/Programs/Security pages | Enabled |
| Prevent ignoring certificate errors | Enabled |
| Turn off InPrivate Browsing | Enabled |
| Turn off Tracking Protection / InPrivate Filtering | Enabled |
| Add-on Management: Deny all add-ons unless specifically allowed | Enabled |
| Turn on ActiveX Filtering | Enabled |
| Restrict File Download / Restrict ActiveX Install (Internet Explorer Processes) | Enabled |
| Prevent Internet Explorer security settings check | Disabled (allow the check) |
| Disable changing connection/proxy/Automatic Configuration settings | Enabled |
| Disable Periodic Check for updates and Automatic Install prompts | Enabled |
| Prevent bypassing SmartScreen Filter warnings | Enabled |
| Prevent participation in the Customer Experience Improvement Program | Enabled |
| Turn off the auto-complete feature for web addresses | Enabled |
| Turn off the security settings check feature | Disabled |
Windows Components — Location and Sensors, NetMeeting, Parental Controls
| Setting | Value |
|---|---|
| Turn off location / location scripting / sensors | Enabled |
| Disable remote Desktop Sharing (NetMeeting) | Enabled |
| Make Parental Control panel visible | Disabled |
Windows Components — Remote Desktop Services (full block)
| Setting | Value |
|---|---|
| Allow users to connect remotely using RD | Disabled (unless required) |
| Automatic reconnection | Disabled |
| Restrict Remote Desktop Services users to a single session | Enabled |
| Do not allow clipboard/COM port/drive/LPT port/smart card redirection | Enabled |
| Do not allow supported Plug and Play device redirection | Enabled |
| Set the RD licensing mode | Enabled, Per User |
| Do not allow client printer redirection | Enabled |
| Always show desktop on connection | Enabled |
| Always prompt for a password upon connection | Enabled |
| Require secure RPC communication | Enabled |
| Require user authentication for remote connections using NLA | Enabled |
| Set client connection encryption level | Enabled, High |
| Set time limit for active but idle RDS sessions | Enabled, 15 min |
| Set time limit for disconnected sessions | Enabled, 10 min |
| Do not use temporary folders per session | Enabled |
Windows Components — RSS Feeds, Search, Security Center
| Setting | Value |
|---|---|
| Turn off addition/removal of feeds | Enabled |
| Turn off background sync for feeds | Enabled |
| Turn off download of enclosures | Enabled |
| Allow indexing of encrypted files | Disabled |
| Do not allow web search | Enabled |
| Prevent adding UNC locations to index | Enabled |
| Prevent indexing email attachments / offline files cache / Outlook / public folders | Enabled |
| Turn on Security Center | Enabled |
Windows Components — Sound Recorder, Tablet PC, Task Scheduler
| Setting | Value |
|---|---|
| Do not allow Sound Recorder to run | Enabled |
| Do not allow Sniping Tool / Windows Journal / InkBall to run | Enabled |
| Turn off automatic learning (Handwriting Personalization) | Enabled |
| Hide Advanced Properties checkbox / Property Pages (Task Scheduler) | Enabled |
| Prohibit Browse / Drag-and-Drop / new task creation / task deletion | Enabled |
Windows Components — Windows Calendar, Color System, Customer Experience
| Setting | Value |
|---|---|
| Turn off Windows Calendar | Enabled |
| Prohibit installing/uninstalling color profiles | Enabled |
| Turn off Customer Experience Improvement Program data collection | Disabled (i.e., turn CEIP off is achieved by Disabling the "allow" toggle — verify against your build's exact wording) |
Windows Components — Windows Defender
| Setting | Value |
|---|---|
| Check for new signatures before scheduled scans | Enabled |
| Turn off real-time monitoring | Disabled (keep real-time monitoring ON) |
| Turn off Windows Defender | Disabled (keep Defender ON) |
| Turn off routinely taking action | Enabled (source value — verify against current Defender terminology on your build, as this UI has changed significantly across Windows versions) |
Windows Components — Windows Error Reporting
| Setting | Value |
|---|---|
| Disable Windows Error Reporting | Enabled |
| Display Error Notification | Disabled |
| Do not send additional data | Enabled |
| Report OS errors / unplanned shutdown events | Disabled |
Windows Components — Windows Explorer, Installer, Logon Options
| Setting | Value |
|---|---|
| Turn off Data Execution Prevention for Explorer | Disabled (i.e., leave DEP protection for Explorer ON) |
| Turn off numerical sorting in Windows Explorer | Enabled |
| Cache transforms in secure location on workstation | Enabled |
| Enable user control over installs | Enabled |
| Prohibit non-admins from applying vendor-signed updates | Enabled |
| Prohibit patching / Prohibit removal of updates / Prohibit user installs | Enabled |
| Turn off creation of System Restore checkpoints (Windows Installer) | Enabled |
| Disable or enable software Secure Attention Sequence | Enabled |
Windows Components — Windows Media, Messenger, Mobility Center, Remote Management
| Setting | Value |
|---|---|
| Do not allow Windows Media Center to run | Enabled |
| Prevent Windows Media DRM Internet Access | Enabled |
| Prevent Desktop shortcut creation / media sharing / Quick Launch shortcut (WMP) | Enabled |
| Do not allow Windows Messenger to be run | Enabled |
| Turn off Windows Mobility Center | Enabled |
| WinRM Client/Server — Allow Basic authentication | Disabled |
| WinRM Client/Server — Allow unencrypted traffic | Disabled |
| WinRM Client/Server — Disallow Kerberos authentication | Disabled (leave Kerberos allowed) |
| Windows Remote Shell — Allow Remote Shell access | Disabled |
Windows Components — Windows SideShow, System Resource Manager, Windows Update
| Setting | Value |
|---|---|
| Require a PIN to access data on devices running Windows SideShow | Enabled |
| Turn off Windows SideShow | Enabled |
| Allow automatic updates immediate installation | Disabled |
| Allow non-admins to receive update notifications | Disabled |
| Configure Automatic Updates | Enabled — auto download & schedule install |
| Do not adjust default option to "install updates and shut down" | Enabled |
| No auto-restart with logged-on users for scheduled installations | Enabled |
| Turn on recommended updates via Automatic Updates | Enabled |
| Turn on Software Notifications | Disabled |
This appendix intentionally preserves the source document's structure and values for reference completeness. Some entries reflect Windows 7/Server 2008-era terminology (e.g., specific Windows Media Center or Tablet PC options) that may not exist on Windows 10/11 images — skip anything not present on your target OS rather than trying to force it.
Things to try / extra points#
Tip:
gpresult /h C:\gpreport.htmlgenerates a full HTML report of currently applied Group Policy settings — a fast way to sanity-check what's actually in effect after you make changes, and a good source for answering forensics questions about current policy state.
gpresult /h C:\gpreport.html
gpupdate /force
gpresultwrites an HTML file toC:\gpreport.html(open it in a browser to review);gpupdate /forceprintsUpdating policy...Computer Policy update has completed successfully.User Policy update has completed successfully.
- "Access is denied" writing to
C:\root without elevation — target a path you own, e.g.C:\Users\<you>\Desktop\gpreport.html. gpupdate /forcedoing nothing/appearing to hang briefly is normal on a non-domain machine (local policy applies almost instantly) — a genuine hang for more than a minute or two suggests a broken GPO client-side extension, in which case reboot instead of waiting.
Tip: On Windows Home editions without
gpedit.msc, many of the same registry-backed policies can still be set directly viaSet-ItemPropertyunderHKLM:\SOFTWARE\Policies\...andHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\...— the GPO editor is just a GUI for registry values in most cases. Search for the specific policy name plus "registry key" if you need the exact path and are on a Home SKU.
Tip: If you want an authoritative source to cross-check this whole section against (rather than just this document), look up the free CIS Microsoft Windows 10/11 Benchmark, published by the Center for Internet Security. It's organized in the same Level 1/Level 2 structure referenced throughout this section, is free to download after a quick registration, and is a legitimate, citable standard if a mentor, judge, or teammate asks "where did this setting come from?"
25. Final Pass / Wrap-Up#
Snapshot Checkpoint — pre-submission: Once everything below checks out and the box is in a good, stable, scoring state, take one more snapshot before you walk away or the round ends. If the VM crashes, gets reset, or something breaks in the last few minutes, this is the checkpoint that saves your final score instead of an earlier, less-hardened one.
- Re-read the README one more time — confirm every explicit requirement is satisfied and nothing required was disabled/removed/uninstalled.
- Re-check the scoring report; note anything still flagged and work it methodically rather than randomly re-clicking settings.
- Confirm you can still log in as an authorized administrator (don't lock yourself out with an over-aggressive UAC/RDP/account change).
- Confirm the firewall is on, Defender/real-time protection is on, and Automatic Updates is configured.
- Confirm no required service was accidentally disabled (re-run
Get-Service | Where Status -eq Runningand sanity-check against the README's required functionality). - Take a final restore point / snapshot once you're in a good, stable, scoring state.
- If time remains, revisit Section 22 and Section 24's full appendix for additional hardening — these are the highest-effort, lowest-urgency items and good use of leftover time.
Final tip: Perfect is the enemy of done — a checklist you complete 90% of beats one you complete 40% of because you got stuck perfecting Administrative Templates minutiae early. Work broad-to-deep: accounts → policy → firewall → services → malware/files → everything else → the deep appendix.