| Round | Attacker | Defender | Winner | Margin |
|---|---|---|---|---|
| 1 | A Red (Team A Attacker) | B Blue (Team B Defender) | B Blue wins | Clean — persistence never fires |
| 2 | B Red (Team B Attacker) | A Blue (Team A Defender) | B Red wins | Persistence fires; A Blue's watchdog only suppresses the artifact |
Team B wins both directions. Their defender beats Team A's attacker by exhaustive enumeration; their attacker beats Team A's defender by hiding in persistence locations the defender never searches.
Observed in the lab: No pwned.txt file was created at any point after reboot. Defender wins cleanly.
A Red.ps1 as Administrator. Four persistence entries planted: Run key AudioSyncHost, scheduled task \AudioSyncMonitor, service AudioSyncProxy, startup shortcut AudioSyncUpdate.lnk.B Blue.ps1. The defender enumerates every persistence location it knows about, comparing each entry name against an embedded JSON whitelist of legitimate Windows entries.AudioSync* names fail the whitelist check. The defender removes the Run key, deletes the scheduled task, disables and removes the service, deletes the startup shortcut.Test-Path returns False.
A Red's payload uses a clever ASCII char-array trick to obfuscate the strings pwned.txt and Pwn3d — designed to evade regex-based detection. But B Blue doesn't grep payloads; it asks a different question: "is this entry name on the list of expected, legitimate Windows entries?" The names AudioSyncHost, AudioSyncMonitor, etc. are invented — they sound like real Windows audio components but don't exist on a clean install. They fail the whitelist regardless of what their payload does.
Lesson: Clever payload obfuscation loses to whitelist enumeration. A defender that asks "is this expected?" inverts the burden of proof from itself to the attacker.
Observed in the lab: After reboot, pwned.txt appears, then disappears, then reappears — but only when the operator chose Defender Watchdog Option 2.
B Red.ps1 as Administrator. Persistence is planted in 10+ locations: HKCU/HKLM Run keys with AES-encrypted payloads, IFEO + SilentProcessExit on userinit.exe, WMI permanent event subscription, PowerShell profile injection, Winlogon Userinit append, BootExecute append, scheduled tasks, services, hijacked existing-task entries. Critical registry keys are armored with TrustedInstaller ownership and Deny ACEs.A Blue.ps1, choosing Watchdog Option 2. A Blue scans Run keys, scheduled tasks, services, startup folders. It does not look at IFEO, WMI, PowerShell profiles, BootExecute, or Winlogon appends. A SYSTEM-level scheduled task is installed that runs every 30 seconds.cmd.exe /c echo Pwn3d > pwned.txt writes the file.pwned.txt, deletes it.SystemUpTime BETWEEN 240 AND 325 matches. WMI consumer fires. pwned.txt is recreated.By the project's win condition — "after reboot, if pwned.txt exists, the attacker wins" — the file does exist after reboot. Repeatedly. The persistence is intact and would re-create the file forever.
A Blue's watchdog is a creative workaround, but it doesn't actually defeat the persistence. It plays whack-a-mole with the artifact. If the operator ran one more reboot without re-arming the watchdog, the file would stay permanently. This is denial of evidence, not defense.
A Blue's detection logic only enumerates four persistence categories: Run keys, scheduled tasks, services, startup folders. B Red plants in those four and in:
userinit.exe (no module checks this)$PROFILE injection (no module checks this)
Even where A Blue does detect a B Red entry, removal often fails: B Red has armored registry keys with TrustedInstaller ownership and Deny ACEs. A Blue's Remove-Item throws ACCESS_DENIED, the exception is caught, the script logs [FAILED] and moves on. The persistence stays in place.
"pwned.txt" as [char[]](112,119,110,101,100,46,116,120,116). The literal string never appears anywhere on disk or in memory until runtime. Defeats every regex hunt for "pwned" or "Pwn3d".[System.IO.File]::Open($p, 4, 3, 1) — FileMode=OpenOrCreate, FileAccess=ReadWrite, FileShare=Read. Any defender's Remove-Item fails because Delete share isn't allowed. The file is immortal while the payload process is alive.Start-Sleep loop keeps the payload process and file lock alive forever.AudioSyncHost, AudioSyncProxy, AudioSyncMonitor all sound like genuine Windows audio subsystem services. A human reviewer might let them through.[Environment]::GetFolderPath('CommonDocuments') instead of the literal "C:\Users\Public\Documents", dodging defenders that flag the \Public\ path string.HKCU:\...\RunOnce that fires on next login — so even if the defender process is killed, it gets a second chance.NT SERVICE\TrustedInstaller and adds Deny ACEs for Everyone. Even an elevated administrator cannot delete these keys without first enabling SeTakeOwnershipPrivilege and reassigning ownership — something most defenders don't do.IFEO\<process>\Debugger hijack, which replaces the executable. SilentProcessExit fires after the process exits naturally — so userinit.exe runs normally and login completes, but the trigger fires as a side effect of the OS reporting the exit. Stealthy and login-safe.SystemUpTime BETWEEN 240 AND 325. Fires exactly once per boot, four minutes in. By that point most defender scans are finished and the user has settled in — the trigger looks like routine WmiPrvSE.exe activity.pwned, Pwn3d, or interpreter names cannot match.Get-ChildItem | Sort LastWriteTime.$APPDATA\Microsoft\Internet Explorer\UserData\iehelper.vbs.Repair-RegistryAclForCleanup helper. Strips Deny ACEs before deletion attempts — designed specifically to defeat the kind of armoring B Red uses on their own attacker (and would defeat it, if the same team were attacking).WinDefend, VMTools, VGAuthService in the broad whitelist (some module ordering may impact VMware Tools temporarily, but the core defender intent is to preserve VM integration).A Red's payload obfuscation is genuinely clever and crushes regex-based defenders. But it does nothing against B Blue's whitelist-by-name approach. The attacker's craft and the defender's detection model were operating at different layers entirely.
A defender that knows about every place persistence can hide beats an attacker who hides cleverly in a place the defender already searches — and beats an attacker who uses fewer hiding places (even if those places are well-armored). B Blue's 16 modules vs A Blue's 4 made all the difference.
A Blue's watchdog never actually removes B Red's persistence. It just keeps wiping the output file. The persistence is still planted, would survive any number of reboots, and would re-emerge instantly if the watchdog ever stopped running. Real defense is rooting out the persistence; suppressing the symptom is denial of evidence.
Once a persistence key is owned by TrustedInstaller and Deny-ACL'd against Everyone, even an elevated administrator's Remove-Item fails. A defender that doesn't explicitly enable SeTakeOwnershipPrivilege, take ownership, and rewrite the ACL cannot remove these entries. Most defenders don't, and they lose.
Standard IFEO Debugger hijacks are well-detected. SilentProcessExit fires after the target process exits normally, so the system functions correctly and the trigger looks like a routine system event. It's safer (no broken logon) and stealthier — a rare combination.
Two cross-team rounds were planned and executed:
Each round was run on a Windows VM in VMware, started from a clean-baseline snapshot. Scripts were executed in elevated PowerShell. After running attacker then defender, the VM was rebooted and C:\Users\Public\Documents\pwned.txt was checked. Snapshots were used to revert between rounds.
Round 1 result observed in the lab matched the static code analysis prediction exactly. Round 2 result also matched the prediction, with the additional observed nuance that A Blue's optional Watchdog Option 2 produces an oscillating — rather than persistent — pwned.txt existence, because it deletes the file in a 30-second loop without removing the underlying persistence.