ScareCrow: How This EDR Bypass Framework Works and How to Detect It

29 July 2025 | 5 min read | justruss.tech

ScareCrow is a payload creation framework built specifically to bypass modern EDR products. It keeps appearing in incident reports and is worth understanding thoroughly from the defensive side. This covers how it works at the implementation level, what telemetry it generates (and what it does not), and how to build detection that holds up against it.

What ScareCrow does

ScareCrow generates loader executables that apply three main evasion layers simultaneously. First, direct syscalls to bypass userland API hooks. Second, Authenticode certificate cloning to make the binary appear signed by a legitimate vendor. Third, a loader chain specifically constructed to avoid the call sequences that EDR products commonly monitor.

Understanding why each layer matters requires understanding what it is bypassing.

Direct syscalls: bypassing userland hooks

Most EDR products work by injecting a monitoring DLL into every process and overwriting the first bytes of sensitive Windows API functions with a JMP instruction that redirects execution through the EDR before the real function runs. ScareCrow generates stub functions that make system calls directly using the syscall instruction with the correct System Service Number (SSN), completely bypassing those hooks.

; ScareCrow-style direct syscall stub for NtAllocateVirtualMemory
; The SSN varies by Windows version - ScareCrow resolves it at runtime
NtAllocateVirtualMemory:
    mov r10, rcx
    mov eax, [ssn_for_NtAllocateVirtualMemory]  ; resolved at runtime
    syscall
    ret

The key point for defenders: this means Sysmon’s Event ID 10 (ProcessAccess) may not fire because the hook DLL never executes. The kernel still processes the operation, so the Microsoft-Windows-Threat-Intelligence ETW provider (ETWTI) does capture it. EDR products with kernel drivers see this. Sysmon-only deployments have a blind spot here.

// Test whether your EDR catches direct syscall operations
// Use a tool like SyscallDumper to verify ETWTI coverage
// In Sysmon logs, check whether Event ID 10 fires when you expect it to
// If it does not, your coverage relies on kernel telemetry you may not have

// Verify EDR kernel driver presence
sc query type= kernel | findstr -i "edr_vendor_name"

// Check loaded kernel drivers
Get-WmiObject Win32_SystemDriver | Where-Object {$_.State -eq "Running"} |
    Select-Object Name, DisplayName, PathName | Format-List

Certificate cloning: making unsigned code look signed

ScareCrow copies the Authenticode signature metadata from a legitimate signed binary and attaches it to the generated payload. The signature does not cryptographically verify because the private key is not available, but many security products do a shallow presence check rather than a full validation. Passing that check causes the binary to be treated as more trustworthy.

// Detection: Sigcheck will show the discrepancy
sigcheck64.exe -nobanner -vt suspect.exe
// Verified:    Signed
// Publisher:   Microsoft Corporation
// Cert Status: This file has a bad image hash
// Description: Windows Host Process
// Version:     (copied from legitimate binary)

// The cert status line is the tell. A certificate present but failing
// validation is stronger evidence of tampering than no certificate at all.

// Sigma rule for invalid signature detection
title: Signed Binary With Invalid Hash
logsource:
    product: windows
    category: image_load
detection:
    selection:
        Signed: 'true'
        SignatureStatus: 'Invalid'
    filter_legit:
        ImageLoaded|startswith:
            - 'C:\Windows\'
            - 'C:\Program Files\'
    condition: selection and not filter_legit
level: high

What the loader chain looks like in telemetry

When a ScareCrow payload executes it allocates a RWX memory region, decodes shellcode into it, and executes it. The memory allocation without a corresponding disk-backed file is the primary indicator that survives the direct syscall evasion.

// Sysmon Event ID 10 will still fire for the target process access
// even with direct syscalls, if the target is lsass.exe or similar
// because ETWTI is active for sensitive targets

// Post-execution memory scan with Volatility malfind
vol -f memory.raw windows.malfind
// Look for:
// Process: updater.exe  Pid: 4892
// Address: 0x1d0000
// Vad Tag: VadS
// Protection: PAGE_EXECUTE_READWRITE
// 4d 5a 90 00 ...  MZ header in anonymous RWX allocation

// Yara rule for ScareCrow-generated loaders in memory
rule ScareCrow_Loader_Memory {
    meta:
        author      = "justruss"
        description = "Detects ScareCrow-style loader in process memory"
        reference   = "https://github.com/optiv/ScareCrow"
    strings:
        // Common string in ScareCrow loaders
        $fiber = "ntdll.ConvertThreadToFiber" ascii wide
        // XOR decryption loop pattern
        $xor_loop = { 48 31 C0 48 FF C0 48 3D ?? ?? ?? ?? 7C F6 }
        // Common export in ScareCrow signed loaders
        $export = "DllRegisterServer" ascii
    condition:
        ($fiber or $xor_loop) and $export
}

Network indicators

ScareCrow payloads establish C2 over HTTPS. The TLS fingerprint of the default configuration produces a recognisable JA3 hash that appears in Zeek ssl.log. Custom profiles change this but default deployments often do not.

// Zeek ssl.log JA3 check
cat ssl.log | zeek-cut ja3 id.orig_h id.resp_h server_name | \
    grep "a0e9f5d64349fb13191bc781f81f42e1"
// Match = likely Cobalt Strike default (common ScareCrow output target)

// Also check for connections from unusual processes to port 443
// Notepad.exe, calc.exe, or other non-network processes making HTTPS connections
// is always worth investigating regardless of what payload generated the beacon

Detection summary

No single detection layer catches ScareCrow reliably because the direct syscall technique specifically targets the most common defensive layer. Layered coverage works: ETWTI for kernel-level process operations, JA3 fingerprinting on network traffic, Yara memory scanning for the loader pattern, and invalid Authenticode signature detection at the process launch layer. Missing any one of these leaves a gap that a ScareCrow payload will likely slip through.