Key Modules and Relevant Functions
- PPL helper (PPLProcessCreator)
- Uses InitializeProcThreadAttributeList + UpdateProcThreadAttribute( PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL) to ask the OS to spawn the child at a specified protection level (example: PROTECTION_LEVEL_ANTIMALWARE_LIGHT or other PPL values).
- Calls CreateProcessW(EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS) with bInheritHandles = TRUE to launch the dumper as a PPL process that inherits the dump file and cancel event handles. This is the crucial step that enables the dumper to target protected processes.
- Process misc / plumbing (ProcessMisc)
- Calls EnableDebugPrivilege() to call AdjustTokenPrivileges and enable SeDebugPrivilege (useful for opening or enumerating system processes).
- Uses NtQuerySystemInformation(SystemProcessInformation) to enumerate processes & threads and find the main thread of the target and to determine whether threads are in the suspended state (IsProcessSuspendedByPID).
- Exposes SuspendProcessByPID which resolves NtSuspendProcess and calls it (after opening the process with PROCESS_SUSPEND_RESUME access). It also has TerminateProcessByPID. These are the low-level primitives to control processes/threads.
- Hardcoded values & notable literals
- "/type 268310" — the repo authors comment this as // dump full. That numeric token appears hardcoded in the dump command-line and is a high-value detection pivot.
- t.txt — the PoC creates a temporary file named t.txt in the process’s current working directory and marks the handle inheritable; it later attempts to delete it. Because the path is relative and it's deleted at the end, the file is often short-lived and can appear in different folders depending on how the tool is launched.
- "/encfile" and "/cancel" — the dumper is passed handle identifiers via these flags, and the tool uses HandleToDecimal(...) to pass the raw handle value as a decimal on the command line.
- "/h" — headless mode for WerFaultSecure.exe.
- Tools within the repo: PPL helper, process helper, monitoring thread logic — the repo automates the timing/race needed to freeze the target.
Why this is more than “just calling WerFaultSecure”
Some initial reactions and reviews of EDR-Freeze suggest that this tool is just a wrapper for WerFaultSecure.exe with some command line arguments however in practice, the PoC implements extra steps that make the technique reliable against hardened targets:
- You must pass an inheritable handle for the dump (so the dumper writes the dump to the passed handle). Creating this handle and ensuring inheritance is non-trivial.
- Protected EDR processes often require a dumper to run at a compatible protection level; the repo includes code to create a PPL process. Without that, a normal user-mode WerFaultSecure.exe invocation likely cannot target a PPL EDR.
- The PoC adds a monitor thread that detects when the dump operation has suspended the target and then suspends the dumper so the target stays suspended — that race & timing logic is the core of keeping the agent “frozen.”
Detection Opportunities
- WerFaultSecure.exe process creation with dump flags — the highest fidelity single indicator is WerFaultSecure.exe launched with /encfile, /cancel, and /type 268310 (in addition to /pid and /h). Hunting for those tokens together dramatically reduces false positives. It’s worth noting that while executions of WerFaultSecure.exe with any command line parameters are rather rare, ARC labs did uncover legitimate activity associated with WerFaultSecure.exe using similar command line options so it is important to make sure that you are doing some correlations of sensitive process ID numbers and any matching werfaultsecure.exe executions.
- ProcessAccess opens requesting PROCESS_SUSPEND_RESUME (0x0800 / decimal 2048) against your EDR/AV process (e.g., MsMpEng.exe, MsSense.exe, vendor agent binaries). Sysmon EventID 10 (ProcessAccess) or Defender DeviceEvents ProcessAccess telemetry will capture the AccessMask/GrantedAccess. This tells you which process attempted to get suspend rights.
- Creation & deletion of t.txt (short-lived) — the repo hardcodes t.txt as the temporary encfile; watch for FileCreate > FileDelete patterns across hosts (any path). Because the path is relative and deleted later, you must capture file create/delete events (Sysmon or Windows file object auditing) to catch this reliably.
- Processes launched with PPL/protection attributes — the PoC uses PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL and CREATE_PROTECTED_PROCESS. If your telemetry exposes a process’ protection level (some EDRs do), alert on unknown/unexpected processes created with PPL levels (e.g., ANTIMALWARE_LIGHT) that are not vendor binaries.
- Agent heartbeat / telemetry gaps — if the EDR process is suspended, the agent’s heartbeat or telemetry will pause. Correlate heartbeat loss with WerFaultSecure/create & ProcessAccess events for high confidence.
- Privilege changes — the tool enables SeDebugPrivilege programmatically. Detecting privilege elevation (or token modifications) by an untrusted binary is a useful supporting signal.
Operational Takeaways
Attackers always go after the eyes and ears. Suspend the agent, and you’ve got a quiet window to operate. Because this runs in user mode and leverages native OS components, kernel hardening isn’t enough.
Two imperatives for defenders:
- Collect the right telemetry. Process creation attributes, protection levels, transient file events, suspend rights, privilege changes, agent heartbeat.
- Assume no single tool is enough. Blend endpoint telemetry with SIEM correlation, agent watchdogs, and fast playbooks that stitch signals together.
The takeaway: don’t rely on one product to cover you, harden your instrumentation and response pipeline now.