How to defend against Run key persistence
Writing to a Run key is normal for installed software and cannot be blocked without breaking it, so the defence is detection and control over what may run. Log registry writes to the Run and RunOnce keys (Sysmon Event ID 13), alert when the value starts a script interpreter or a binary often used to run code, review autostart entries with Autoruns, and use App Control for Business so that an unapproved program does not run at logon even if it is registered.
What the attacker does
Every value under these keys starts a program when a user logs on:
HKCU\Software\Microsoft\Windows\CurrentVersion\RunandRunOnce: for the current user. Any user can write here without administrator rights.HKLM\Software\Microsoft\Windows\CurrentVersion\RunandRunOnce: for every user. Writing here needs administrator rights.
An attacker who has run code once adds a value so that the code runs again after every reboot. RunOnce values are deleted after they run.
What it looks like in the logs
A registry value set event (Sysmon Event ID 13, category: registry_set): TargetObject is the full path of the value, Details is the command that will run, Image is the program that wrote it. One of the two entries in the recordings, written by a post-exploitation framework:
| Image | C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe |
|---|---|
| TargetObject | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Updater |
| Details | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -c "$x=$((gp HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion Debug).Debug);powershell -Win Hidden -enc $x" |
| EventType | SetValue |
The value starts PowerShell, which reads its real script from another registry value. Installed software usually registers its own executable instead.
Detect
Measured on the challenge data: the rule caught 2 of 2 attack events and matched 1 of 9,691 normal events.
Show the rule (try the challenge first)
title: Run key value that starts a script interpreter
id: 5e7f0a3c-9d28-4b61-8e4a-2c6b1f9d7a05
status: test
description: Detects a value written under a Run or RunOnce key whose command starts a script interpreter or a system binary often used to run code. Installed software normally registers its own executable.
references:
- https://attack.mitre.org/techniques/T1547/001/
- https://howdefend.com/defend/run-key-persistence/
author: Bartu Kılıç
date: 2026-10-20
tags:
- attack.persistence
- attack.t1547.001
logsource:
product: windows
category: registry_set
detection:
selection_key:
TargetObject|contains:
- '\CurrentVersion\Run\'
- '\CurrentVersion\RunOnce\'
selection_value:
Details|contains:
- 'powershell'
- 'pwsh'
- 'mshta'
- 'wscript'
- 'cscript'
- 'rundll32'
- 'regsvr32'
- 'cmd.exe'
condition: all of selection_*
falsepositives:
- Software that registers a script or a rundll32 command at logon (review the Details value)
level: medium
What the rule misses
- A dropped executable. If the value points to the attacker's own program, for example in
AppData, no interpreter appears inDetails. Installed software also lives inAppData(on the clean client, Spotify and a Python installer register values that point there), so the folder alone separates nothing; App Control does. - Other autostart locations. The Startup folder, services, scheduled tasks, Winlogon values and the other keys listed by ATT&CK each need their own rule.
- One known false positive. On the clean Windows 10 client, the OneDrive installer registered a
RunOncevalue that runscmd.exe /q /c rmdir /s /qon its old version folder. Filter it by the full value, not bycmd.exe. - Missing logging. Sysmon only records the keys its configuration includes. Check that the configuration in use covers the Run keys before relying on the rule.
Prevent
- Control what runs, not where it is registered. With App Control for Business or AppLocker enforced, a registered program that is not allowed by the policy does not start at logon.
- Review the list. Autoruns (Sysinternals) lists every autostart location with signature and publisher information; comparing its output between machines shows entries that only one machine has.
Practice
Write the rule yourself on the same data, with every target labelled.