diff --git a/samples/LoadInText.dll b/samples/LoadInText.dll new file mode 100644 index 0000000..923073e Binary files /dev/null and b/samples/LoadInText.dll differ diff --git a/samples/README.md b/samples/README.md new file mode 100644 index 0000000..89c8d5a --- /dev/null +++ b/samples/README.md @@ -0,0 +1,455 @@ +# StackSentry Sample Corpus + +This folder contains a curated lab corpus for validating StackSentry detections. These files are intentionally suspicious and should be executed only in a controlled VM or malware-analysis lab. + +Run every command from the repository root after building StackSentry. + +Source build: + +```powershell +.\build.ps1 +``` + +The call stack values below are representative StackSentry stack summaries captured at the sensitive DLL-load event. ASLR, Windows build, loaded modules, and timeout timing can change offsets and occasionally the exact lower frames, but the suspicious pattern should remain the same. + +## Recommended Starting Commands + +First safe pass: + +```powershell +.\build\StackSentry64.exe /run sample.exe /quick /no-target-output /timeout 5000 +``` + +Strong default for suspicious loaders: + +```powershell +.\build\StackSentry64.exe /run sample.exe /max /no-target-output /timeout 10000 +``` + +Anti-evasion hunting bundle: + +```powershell +.\build\StackSentry64.exe /run sample.exe /max /hunt /no-target-output /timeout 15000 +``` + +Hidden proxy/gadget origin: + +```powershell +.\build\StackSentry64.exe /run sample.exe /max /regtrace /no-target-output /timeout 10000 +``` + +Network API use attribution is explicit and not part of `/hunt`: + +```powershell +.\build\StackSentry64.exe /run sample.exe /max /hunt /network-use-trace /no-target-output /timeout 30000 +``` + +Remote loader that injects into another process: + +```powershell +.\build\StackSentry64.exe /run loader.exe /max /follow-remote /regtrace /no-target-output /timeout 15000 +``` + +Keep the target alive after timeout for debugger inspection: + +```powershell +.\build\StackSentry64.exe /run target.exe /max /no-target-output /timeout 10000 /keep-alive +``` + +Full stack in one line, without repeated-frame compression: + +```powershell +.\build\StackSentry64.exe /run target.exe /max /inline-stack /no-target-output /timeout 10000 +``` + +Full stack frame-by-frame with module offsets: + +```powershell +.\build\StackSentry64.exe /run target.exe /max /full-stack /no-target-output /timeout 10000 +``` + +## Files + +| File | Purpose | +| --- | --- | +| `sample_00_pic_runner.exe` | Runs a PIC payload passed after `--`. | +| `sample_01_pic_loadlibrary_proxy_runner.exe` | Runs a PIC payload after preloading `nvwgf2umx.dll` as a local gadget carrier. | +| `payload_01_pic_loadlibrary_proxy.bin` | PIC LoadLibrary proxy payload used with `sample_01_pic_loadlibrary_proxy_runner.exe`. | +| `sample_02_ldrloaddll_direct.exe` | Direct `LdrLoadDll` origin-trace test. | +| `sample_03_text_section_proxy.exe` | Shellcode/proxy execution from executable image `.text`. | +| `sample_04_text_section_code_cave.exe` | Code-cave gadget / modified image detection test. | +| `sample_05_dll_payload_host.exe` | Host that loads `LoadInText.dll`, then runs a DLL-mode payload. | +| `LoadInText.dll` | Dependency for `sample_05_dll_payload_host.exe`; keep this exact name. | +| `sample_06_veh_context_origin.exe` | VEH-context origin-correlation test. | +| `sample_07_silentmoon_direct.exe` | SilentMoonwalk-style stack spoofing, one-shot DLL load. | +| `sample_08_silentmoon_synthetic.exe` | Synthetic stack variant intended to remove the obvious unbacked tail frame. | +| `payload_09_silentmoon_rdi.bin` | Donut/RDI payload for SilentMoonwalk coverage. | +| `payload_10_silentmoon_rdi_synthetic.bin` | Donut/RDI synthetic-stack payload for stronger stack-spoofing coverage. | +| `sample_11_silentmoon_rdi_threaded.exe` | Threaded SilentMoonwalk/RDI harness. | +| `payload_12_byoud_rdi.bin` | Donut/RDI BYOUD payload. | +| `byoud.dll` | Dependency for the BYOUD payload; keep this exact name. | +| `sample_13_massdriver_dispatch.exe` | MassDriver-like cross-thread function dispatch test. | +| `sample_14_threadpool_chain.exe` | Threadpool callback-chain proxy test. | +| `sample_15_remote_victim.exe` | Remote-injection victim process. | +| `sample_16_remote_shellcode_injector.exe` | Injector for `sample_15_remote_victim.exe`; pass the victim PID. | +| `sample_17_network_reuse_probe.exe` | Reuses an already-loaded network DLL from private executable memory. | +| `nvwgf2umx.dll` | Support DLL used by gadget-search payloads on machines without a suitable local module. | + +## Exact Test Commands + +### 1. PIC LoadLibrary Proxy Payload + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_01_pic_loadlibrary_proxy_runner.exe /max /regtrace /no-target-output /timeout 25000 -- .\samples\payload_01_pic_loadlibrary_proxy.bin +``` + +Expected DLL-load stack: + +```text +wininet: + kernelbase.dll|kernelbase.dll|nvwgf2umx.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Expected attribution: + +```text +source: register_trace_thread_start kind=thread_start_origin +origin: Unbacked +``` + +### 2. Direct LdrLoadDll + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_02_ldrloaddll_direct.exe /max /regtrace /no-target-output /timeout 9000 +``` + +Expected DLL-load stack: + +```text +wininet.dll: + Unbacked +``` + +Expected attribution: + +```text +source: execution_guard kind=proxy_transfer +origin: sample_02_ldrloaddll_direct.exe +``` + +### 3. Image .text Proxy + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_03_text_section_proxy.exe /max /hunt /no-target-output /timeout 13000 +``` + +Expected DLL-load stack: + +```text +wininet: + kernelbase.dll|kernelbase.dll|nvwgf2umx.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Expected attribution: + +```text +source: register_trace_thread_start kind=thread_start_origin +origin: sample_03_text_section_proxy.exe +``` + +### 4. Image Code Cave / Modified Module + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_04_text_section_code_cave.exe /max /hunt /no-target-output /timeout 13000 +``` + +Expected DLL-load stack: + +```text +wininet: + kernelbase.dll|kernelbase.dll|BackedModified +``` + +Expected attribution: + +```text +source: temporal_image_stomp kind=image_stomp_origin +modified module: ucrtbased.dll or another writable code-cave target +``` + +### 5. DLL-Mode Payload Host + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_05_dll_payload_host.exe /max /regtrace /no-target-output /timeout 13000 +``` + +Expected DLL-load stack: + +```text +wininet: + kernelbase.dll|kernelbase.dll|nvwgf2umx.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Expected attribution: + +```text +source: execution_guard kind=proxy_transfer +origin: LoadInText.dll +``` + +### 6. VEH Context Origin + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_06_veh_context_origin.exe /regtrace /no-target-output /timeout 13000 +``` + +This sample uses a VEH exception path to redirect `RIP` before the proxy DLL load. `/regtrace` tracks the dynamic executable transition and correlates the redirected RIP back to the origin that disappears from the final DLL-load stack. + +Expected DLL-load stack: + +```text +wininet: + kernelbase.dll|kernelbase.dll|nvwgf2umx.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Expected attribution: + +```text +source: veh_context kind=veh_rip_origin +origin: VEH redirected RIP that is absent from the final DLL-load stack +``` + +### 7. SilentMoonwalk Direct + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_07_silentmoon_direct.exe /max /stack-audit /regtrace /no-target-output /timeout 9000 +``` + +Expected DLL-load stack: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernel32.dll|ntdll.dll +``` + +Expected detection: + +```text +rules: stack_audit_return_frame_without_matching_call, sensitive_dll_load_origin_hidden_by_register_trace +source: execution_guard kind=proxy_transfer +``` + +### 8. SilentMoonwalk Synthetic Stack + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_08_silentmoon_synthetic.exe /max /stack-audit /regtrace /no-target-output /timeout 9000 +``` + +Expected DLL-load stack: + +```text +ws2_32.dll: + kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernel32.dll|ntdll.dll +``` + +Expected detection: + +```text +rules: return_address_without_plausible_callsite, stack_audit_return_frame_without_matching_call +source: execution_guard kind=proxy_transfer +``` + +### 9. SilentMoonwalk RDI Payload + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_00_pic_runner.exe /max /stack-audit /regtrace /no-target-output /timeout 12000 -- .\samples\payload_09_silentmoon_rdi.bin +``` + +Expected DLL-load stacks: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +mscoree.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +ws2_32.dll: + kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|Unbacked +``` + +The `wininet.dll` and `mscoree.dll` loads usually come from the Donut/RDI bootstrap. The `ws2_32.dll` load is the SilentMoonwalk test stage. + +### 10. SilentMoonwalk RDI Synthetic Stack + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_00_pic_runner.exe /max /stack-audit /regtrace /memory-audit /no-target-output /timeout 12000 -- .\samples\payload_10_silentmoon_rdi_synthetic.bin +``` + +Expected DLL-load stacks: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +mscoree.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +ws2_32.dll: + kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernel32.dll|ntdll.dll +``` + +This is one of the strongest screenshot samples because the final `ws2_32.dll` stack can look fully backed while StackSentry still attributes the hidden origin. + +### 11. Threaded SilentMoonwalk/RDI Harness + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_11_silentmoon_rdi_threaded.exe /max /stack-audit /regtrace /memory-audit /no-target-output /timeout 12000 +``` + +Expected DLL-load stacks: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +mscoree.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +ws2_32.dll: + kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|kernelbase.dll|Unbacked +``` + +### 12. BYOUD RDI / Unwind Metadata Spoofing + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_00_pic_runner.exe /max /hunt /no-target-output /timeout 30000 -- .\samples\payload_12_byoud_rdi.bin +``` + +Expected bootstrap DLL-load stacks: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|Unbacked + +mscoree.dll: + kernelbase.dll|kernelbase.dll|Unbacked +``` + +Expected BYOUD target-stage DLL-load stack when the payload reaches the network DLL call: + +```text +ws2_32.dll: + kernelbase.dll|kernelbase.dll|ntdll.dll|kernelbase.dll|kernel32.dll|ntdll.dll +``` + +Expected BYOUD findings: + +```text +rules: byoud_runtime_function_unwind_hijack +rules: byoud_unwind_info_tampered +source: byoud_register_trace kind=byoud_hidden_loader_origin +origin: byoud hidden loader context +``` + +`byoud_unwind_section_protection_changed` may also appear when the monitor observes the protection transition around unwind metadata, but the core proof for this sample is the runtime-function / unwind-info divergence plus the `ws2_32.dll` load attributed through `byoud_register_trace`. + +The BYOUD stage is more timing-sensitive than the smaller samples. If only the bootstrap loads appear, rerun with a longer timeout. + +### 13. MassDriver-Style Thread Message Dispatch + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_13_massdriver_dispatch.exe /max /dispatch-trace /regtrace /no-target-output /timeout 12000 +``` + +Expected DLL-load stack: + +```text +wininet.dll: + kernelbase.dll|kernelbase.dll|sample_13_massdriver_dispatch.exe|kernel32.dll|ntdll.dll +``` + +Expected dispatch trace: + +```text +source: thread_message_dispatch kind=function_proxy_dispatch +requester: Unbacked +worker caller: sample_13_massdriver_dispatch.exe +function: LoadLibraryA +argument: wininet.dll +``` + +### 14. Threadpool Callback Chain + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_14_threadpool_chain.exe /max /threadpool-chain-trace /no-target-output /timeout 12000 +``` + +Expected DLL-load stack: + +```text +winhttp.dll: + kernelbase.dll|kernelbase.dll|wininet.dll|kernelbase.dll|ntdll.dll|kernelbase.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Expected attribution: + +```text +source: threadpool_chain_context kind=threadpool_chain_context +origin: sample_14_threadpool_chain.exe +visible caller: wininet.dll or another clean gadget module +``` + +This sample requires `/threadpool-chain-trace`. `/hunt` does not enable the threadpool chain hooks by default, so a run without this flag may show the DLL load in external tools while StackSentry stays quiet. + +### 15. Remote Follow + +Start the victim first, capture its PID, then run the injector under StackSentry: + +```powershell +$victim = Start-Process .\samples\sample_15_remote_victim.exe -PassThru +.\build\StackSentry64.exe /run .\samples\sample_16_remote_shellcode_injector.exe /max /follow-remote /regtrace /no-target-output /timeout 18000 -- $($victim.Id) +``` + +Expected remote-follow telemetry: + +```text +remote_follow:OpenProcess: +remote_follow:NtCreateThreadEx: +remote_follow:SetThreadContext: +remote_follow:ResumeThread: +``` + +Optional DLL-load stack in the instrumented victim, when the injected payload reaches the network DLL load: + +```text +wininet: + kernelbase.dll|kernelbase.dll|nvwgf2umx.dll|ntdll.dll|ntdll.dll|kernel32.dll|ntdll.dll +``` + +Clean up the victim if it is still running: + +```powershell +Stop-Process -Id $victim.Id -Force +``` + +### 16. Network DLL Reuse From Private Executable Memory + +```powershell +.\build\StackSentry64.exe /run .\samples\sample_17_network_reuse_probe.exe /max /network-use-trace /no-target-output /timeout 8000 +``` + +Expected network-use stack: + +```text +ws2_32.dll!getaddrinfo: + Unbacked +``` + +Expected detection: + +```text +rules: network_api_called_from_unbacked_executable_memory +caller: Unbacked +``` + diff --git a/samples/byoud.dll b/samples/byoud.dll new file mode 100644 index 0000000..aeff2b7 Binary files /dev/null and b/samples/byoud.dll differ diff --git a/samples/nvwgf2umx.dll b/samples/nvwgf2umx.dll new file mode 100644 index 0000000..bbe78f5 Binary files /dev/null and b/samples/nvwgf2umx.dll differ diff --git a/samples/payload_01_pic_loadlibrary_proxy.bin b/samples/payload_01_pic_loadlibrary_proxy.bin new file mode 100644 index 0000000..423df89 Binary files /dev/null and b/samples/payload_01_pic_loadlibrary_proxy.bin differ diff --git a/samples/payload_09_silentmoon_rdi.bin b/samples/payload_09_silentmoon_rdi.bin new file mode 100644 index 0000000..bab7e0b Binary files /dev/null and b/samples/payload_09_silentmoon_rdi.bin differ diff --git a/samples/payload_10_silentmoon_rdi_synthetic.bin b/samples/payload_10_silentmoon_rdi_synthetic.bin new file mode 100644 index 0000000..6da5553 Binary files /dev/null and b/samples/payload_10_silentmoon_rdi_synthetic.bin differ diff --git a/samples/payload_12_byoud_rdi.bin b/samples/payload_12_byoud_rdi.bin new file mode 100644 index 0000000..ce91ecf Binary files /dev/null and b/samples/payload_12_byoud_rdi.bin differ diff --git a/samples/sample_00_pic_runner.exe b/samples/sample_00_pic_runner.exe new file mode 100644 index 0000000..fe0a7c0 Binary files /dev/null and b/samples/sample_00_pic_runner.exe differ diff --git a/samples/sample_01_pic_loadlibrary_proxy_runner.exe b/samples/sample_01_pic_loadlibrary_proxy_runner.exe new file mode 100644 index 0000000..d54c646 Binary files /dev/null and b/samples/sample_01_pic_loadlibrary_proxy_runner.exe differ diff --git a/samples/sample_02_ldrloaddll_direct.exe b/samples/sample_02_ldrloaddll_direct.exe new file mode 100644 index 0000000..05d7589 Binary files /dev/null and b/samples/sample_02_ldrloaddll_direct.exe differ diff --git a/samples/sample_03_text_section_proxy.exe b/samples/sample_03_text_section_proxy.exe new file mode 100644 index 0000000..8b1c66c Binary files /dev/null and b/samples/sample_03_text_section_proxy.exe differ diff --git a/samples/sample_04_text_section_code_cave.exe b/samples/sample_04_text_section_code_cave.exe new file mode 100644 index 0000000..ee6ada6 Binary files /dev/null and b/samples/sample_04_text_section_code_cave.exe differ diff --git a/samples/sample_05_dll_payload_host.exe b/samples/sample_05_dll_payload_host.exe new file mode 100644 index 0000000..f1d8eb6 Binary files /dev/null and b/samples/sample_05_dll_payload_host.exe differ diff --git a/samples/sample_06_veh_context_origin.exe b/samples/sample_06_veh_context_origin.exe new file mode 100644 index 0000000..ac8d3c4 Binary files /dev/null and b/samples/sample_06_veh_context_origin.exe differ diff --git a/samples/sample_07_silentmoon_direct.exe b/samples/sample_07_silentmoon_direct.exe new file mode 100644 index 0000000..b87c7e7 Binary files /dev/null and b/samples/sample_07_silentmoon_direct.exe differ diff --git a/samples/sample_08_silentmoon_synthetic.exe b/samples/sample_08_silentmoon_synthetic.exe new file mode 100644 index 0000000..0d1b87f Binary files /dev/null and b/samples/sample_08_silentmoon_synthetic.exe differ diff --git a/samples/sample_11_silentmoon_rdi_threaded.exe b/samples/sample_11_silentmoon_rdi_threaded.exe new file mode 100644 index 0000000..2f1af61 Binary files /dev/null and b/samples/sample_11_silentmoon_rdi_threaded.exe differ diff --git a/samples/sample_13_massdriver_dispatch.exe b/samples/sample_13_massdriver_dispatch.exe new file mode 100644 index 0000000..e860ddd Binary files /dev/null and b/samples/sample_13_massdriver_dispatch.exe differ diff --git a/samples/sample_14_threadpool_chain.exe b/samples/sample_14_threadpool_chain.exe new file mode 100644 index 0000000..65b5ea5 Binary files /dev/null and b/samples/sample_14_threadpool_chain.exe differ diff --git a/samples/sample_15_remote_victim.exe b/samples/sample_15_remote_victim.exe new file mode 100644 index 0000000..d08d1a0 Binary files /dev/null and b/samples/sample_15_remote_victim.exe differ diff --git a/samples/sample_16_remote_shellcode_injector.exe b/samples/sample_16_remote_shellcode_injector.exe new file mode 100644 index 0000000..255ca75 Binary files /dev/null and b/samples/sample_16_remote_shellcode_injector.exe differ diff --git a/samples/sample_17_network_reuse_probe.exe b/samples/sample_17_network_reuse_probe.exe new file mode 100644 index 0000000..0cbacd0 Binary files /dev/null and b/samples/sample_17_network_reuse_probe.exe differ