T1129

Shared Modules

Execution Last updated:

Adversaries may execute malicious payloads by loading shared modules into running processes. Shared modules are executable files (DLLs on Windows, .so on Linux, .dylib on macOS) loaded at runtime to provide reusable code or access OS API functions. Adversaries abuse this by loading malicious shared objects from arbitrary local paths or UNC network paths, allowing payload execution within the memory space of a legitimate host process. Windows uses LoadLibrary/LoadLibraryEx (via NTDLL.dll Native API), Linux uses dlopen/dlsym from dlfcn.h, and macOS uses both dlopen and Objective-C runtime calls. This technique enables modular malware architectures where the main dropper loads additional capability modules — seen in gh0st RAT, Astaroth, RotaJakiro, FoggyWeb, and BLINDINGCAN.

What is T1129 Shared Modules?

Shared Modules (T1129) maps to the Execution tactic — the adversary is trying to run malicious code in MITRE ATT&CK.

This page provides production-ready detection logic for Shared Modules, covering the data sources and telemetry it touches: Module: Module Load, Process: Process Creation, Microsoft Defender for Endpoint. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Execution
Technique
T1129 Shared Modules
Canonical reference
https://attack.mitre.org/techniques/T1129/
Microsoft Sentinel / Defender
kusto
let SuspiciousLoadPaths = dynamic([
  "\\AppData\\Local\\Temp\\",
  "\\AppData\\Roaming\\",
  "\\Users\\Public\\",
  "\\ProgramData\\Microsoft\\Windows\\Start Menu\\",
  "\\Windows\\Temp\\",
  "C:\\Temp\\",
  "C:\\tmp\\",
  "\\Downloads\\"
]);
let UNCPathPattern = @"\\\\[^\\]+\\[^\\]+\\.*\.dll";
let KnownGoodDirs = dynamic([
  "\\Windows\\System32\\",
  "\\Windows\\SysWOW64\\",
  "\\Windows\\WinSxS\\",
  "\\Program Files\\",
  "\\Program Files (x86)\\"
]);
DeviceImageLoadEvents
| where Timestamp > ago(24h)
| where FileName endswith ".dll"
| where not(FolderPath has_any (KnownGoodDirs))
| where FolderPath has_any (SuspiciousLoadPaths)
    or FolderPath matches regex UNCPathPattern
    or (InitiatingProcessFileName in~ ("rundll32.exe", "regsvr32.exe", "mshta.exe", "wscript.exe", "cscript.exe", "msbuild.exe", "installutil.exe") and not(FolderPath has_any (KnownGoodDirs)))
| extend IsUNCPath = FolderPath matches regex @"^\\\\\\\\[^\\]+"
| extend IsTempPath = FolderPath has_any (SuspiciousLoadPaths)
| extend IsSuspiciousLoader = InitiatingProcessFileName in~ ("rundll32.exe", "regsvr32.exe", "mshta.exe", "wscript.exe", "cscript.exe", "msbuild.exe", "installutil.exe")
| extend IsUnsigned = isempty(Signer) or Signer == "" or IsCertificateValid == false
| project Timestamp, DeviceName, AccountName,
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         FileName, FolderPath, SHA256,
         Signer, IsCertificateValid,
         IsUNCPath, IsTempPath, IsSuspiciousLoader, IsUnsigned
| sort by Timestamp desc

Detects suspicious DLL/shared module loading via Microsoft Defender for Endpoint DeviceImageLoadEvents. Identifies modules loaded from high-risk locations (Temp, AppData, Public, Windows\Temp), UNC network paths, and suspicious host processes (rundll32, regsvr32, mshta, wscript, msbuild, installutil) loading from non-standard directories. Augments signal by flagging unsigned or invalid-certificate modules. This covers Windows LoadLibrary/LoadLibraryEx abuse patterns seen in modular malware families.

high severity medium confidence

Data Sources

Module: Module Load Process: Process Creation Microsoft Defender for Endpoint

Required Tables

DeviceImageLoadEvents

False Positives

  • Legitimate software installers temporarily staging DLLs in %TEMP% before moving them to installation directories
  • Developer tools (Visual Studio, JetBrains IDEs) loading debug or test assemblies from user-writable paths during development builds
  • Enterprise software with non-standard installation paths (e.g., installed to C:\Tools or user home directories by portable apps)
  • Security tools and EDR agents loading kernel modules or helper DLLs from non-standard paths during startup
  • Virtualization software (VMware Tools, VirtualBox Guest Additions) loading drivers from paths outside System32

Sigma rule & cross-platform mapping

The detection logic for Shared Modules (T1129) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Load DLL from Temp Directory via rundll32

    Expected signal: Sysmon Event ID 7 (ImageLoad): ImageLoaded path will be %TEMP%\df00tech-test-module.dll, Image will be C:\Windows\System32\rundll32.exe. Sysmon Event ID 1 (Process Create): rundll32.exe with command line containing the Temp path. Security Event ID 4688 if command line auditing is enabled.

  2. Test 2Load DLL via PowerShell Assembly.LoadFile from AppData

    Expected signal: Sysmon Event ID 7: ImageLoaded will show AppData\Roaming\df00tech-module.dll loaded by powershell.exe. Sysmon Event ID 1: PowerShell process creation with LoadFile command. Sysmon Event ID 11: File creation of df00tech-module.dll in AppData\Roaming.

  3. Test 3Load Shared Object from /tmp via dlopen on Linux

    Expected signal: Auditd syscall events: openat(2) call to /tmp/df00tech_test_module.so from python3 process. Linux audit event type=EXECVE for gcc and python3. If using Falco or Sysdig: proc.name=python3 with fd.name=/tmp/*.so triggers shared lib load from tmp rule. Syslog entry if auditd is configured to monitor /tmp for file opens.

  4. Test 4Regsvr32 Loading Unregistered DLL from User-Writable Path

    Expected signal: Sysmon Event ID 7 (ImageLoad): ImageLoaded=C:\Windows\Temp\df00tech-reg-test.dll, Image=C:\Windows\System32\regsvr32.exe. Sysmon Event ID 1: regsvr32.exe with /s flag and the temp path. The /s flag suppresses the dialog box — this silence flag is itself a behavioral indicator used in malware deployment.

  5. Test 5Load dylib from /tmp on macOS via Python ctypes

    Expected signal: macOS Endpoint Security Framework: ES_EVENT_TYPE_NOTIFY_MMAP event for the dylib mmap into python3 process address space. Unified log (log stream --predicate 'subsystem == "com.apple.dyld"') shows dylib load from /tmp. If Jamf Protect or CrowdStrike Falcon is deployed: 'Shared Library Loaded from /tmp' detection fires.


Response Playbook

Triage

  1. Identify the full path of the loaded module — is it in a user-writable location (Temp, AppData, Downloads, C:\Temp)? Modules loaded from these paths are high-priority unless the loading process is a known installer.
  2. Examine the loading process (InitiatingProcessFileName / Image) — legitimate system processes rarely load DLLs from temp directories. Focus immediately on rundll32, regsvr32, mshta, wscript, and msbuild loading from non-System32 locations.
  3. Check the module's digital signature — unsigned DLLs or DLLs with invalid/revoked certificates loaded by system processes are strongly suspicious. Query: DeviceImageLoadEvents | where SHA256 == '<hash>' | project Signer, IsCertificateValid.
  4. Hash the loaded module and submit to VirusTotal or your threat intel platform — malicious shared modules used by modular malware families (gh0st RAT, Astaroth, RotaJakiro) will frequently have existing detections.
  5. Review the parent process chain — what spawned the loading process? Office applications, browser processes, or unusual script interpreters loading DLLs from temp paths indicate phishing-delivered malware.
  6. Check for concurrent or preceding file drop events — was the suspicious DLL written to disk moments before loading? Correlate DeviceFileEvents (Sysmon 11) for the same file path within a 60-second window.
  7. Assess the loaded module's exports — if you can retrieve the file, run 'dumpbin /exports <dll>' or 'strings' on it to identify suspicious function names or C2 indicators before initiating containment.

Containment

  1. If the module is confirmed malicious: immediately isolate the endpoint using EDR network isolation or VLAN quarantine to prevent C2 communication from the loaded payload.
  2. Identify all processes that loaded the suspicious module (DeviceImageLoadEvents | where SHA256 == '<hash>') — there may be multiple instances across the same host or lateral movement to other hosts.
  3. Kill the hosting process if it is non-critical (wscript.exe, mshta.exe, rundll32.exe loaded from temp) — use EDR process termination, not Task Manager, to preserve forensic state.
  4. Block the module's SHA256 hash at the EDR/AV layer immediately to prevent re-execution if the dropper attempts to re-deploy the module.
  5. If UNC path loading detected: block access to the network share at the firewall level and investigate the source server for compromise — UNC-loaded modules indicate lateral movement or a network-resident staging server.
  6. If the user account context is a service account or privileged account: rotate credentials immediately and audit all recent actions by that account in Azure AD / Active Directory logs.

Evidence Collection

  1. Sysmon Event ID 7 (ImageLoad) — captures the full path, hash, and signature status of every loaded module. The primary source for this technique.
  2. Sysmon Event ID 1 (Process Create) — captures the spawning of the loading process, its parent, and the full command line including any DLL path arguments passed to rundll32/regsvr32.
  3. Sysmon Event ID 11 (FileCreate) — correlate to find when the malicious module was written to disk and which process dropped it.
  4. Sysmon Event ID 3 (NetworkConnect) — identify outbound C2 connections initiated by the process that loaded the module.
  5. MDE DeviceImageLoadEvents — query for all modules loaded by the suspicious process over the incident timeframe to map all loaded capability modules.
  6. File system: recover the DLL/SO/dylib from the disk path before containment cleans it — hash it, extract strings, and identify exports using 'dumpbin /exports' (Windows), 'nm -D' (Linux), or 'otool -l' (macOS).
  7. Memory forensics (Volatility 'dlllist' plugin) — if the module was loaded reflectively (not written to disk), memory analysis may be the only way to recover the payload.
  8. Prefetch files: C:\Windows\Prefetch\RUNDLL32.EXE-*.pf — contains the list of DLLs loaded during each rundll32 execution with timestamps.
  9. Windows Event ID 4688 (Security log) — process creation with command line auditing captures rundll32/regsvr32 invocations with DLL path arguments.
  10. Linux: /proc/<pid>/maps — shows all mapped shared objects for a running process; /var/log/audit/audit.log with auditd syscall monitoring for execve and openat calls to .so files.

Escalation Criteria

  • ! Module loaded from a UNC network path — indicates a network-resident staging server and potential lateral movement infrastructure; escalate to P1 immediately.
  • ! Unsigned DLL loaded by a critical system process (lsass.exe, svchost.exe, services.exe) — indicates process injection or DLL hijacking combined with shared module loading.
  • ! Multiple endpoints loading the same suspicious module hash within a short time window — indicates automated lateral movement or worm-like propagation.
  • ! Module exports or strings analysis reveals C2 indicators (hardcoded IPs, domains, encryption keys) — confirms active malware deployment.
  • ! The loading process chain traces back to a phishing email attachment (Outlook spawning wscript/mshta which loads a DLL) — indicates initial access via phishing with modular payload delivery.
  • ! Module loaded by a privileged process (running as SYSTEM or Domain Admin) with no corresponding change ticket — indicates privilege escalation or credential compromise prior to module loading.

Investigation Guide

Forensic Artifacts

  • > Windows — Prefetch: C:\Windows\Prefetch\RUNDLL32.EXE-*.pf and C:\Windows\Prefetch\REGSVR32.EXE-*.pf list all DLLs loaded per execution with timestamps
  • > Windows — MFT ($MFT): Master File Table entries for the DLL file, including creation, modification, and access timestamps (detect timestomping by comparing SI vs FN attributes)
  • > Windows — AppCompatCache (ShimCache): HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache — records DLL execution timestamps on older Windows versions
  • > Windows — Amcache.hve: C:\Windows\AppCompat\Programs\Amcache.hve — contains SHA1 hashes and paths of executed/loaded modules
  • > Windows — Registry: HKLM\SYSTEM\CurrentControlSet\Services — service DLLs referenced here; malicious modules may register as service DLLs (ServiceDll value under HKLM\SYSTEM\...\Services\<svc>\Parameters)
  • > Linux — /proc/<pid>/maps: real-time view of all mapped shared libraries for a running process including load addresses
  • > Linux — /proc/<pid>/fd: file descriptors showing open .so files referenced by a process
  • > Linux — ld.so.cache (/etc/ld.so.cache): precompiled list of known shared libraries; a tampered cache can redirect dlopen calls to malicious paths
  • > Linux — LD_PRELOAD: environment variable that forces .so loading before all others — check /proc/<pid>/environ for malicious preloads
  • > macOS — dyld shared cache (/private/var/db/dyld/): Apple's shared library cache; modifications here indicate OS-level tampering
  • > macOS — DYLD_INSERT_LIBRARIES: environment variable equivalent to LD_PRELOAD on macOS — check process environment for unexpected values
  • > Memory — Volatility 'dlllist' plugin: enumerate all DLLs loaded in process VAD (Virtual Address Descriptor) tree, revealing reflectively loaded modules not present on disk

Tuning Guidance

T1129 detection requires careful baselining to avoid alert fatigue from legitimate software behavior. Start by inventorying your environment's legitimate DLL loading patterns before enabling alerting. Key tuning steps: (1) Identify software that legitimately loads from user-writable paths — common offenders include Python/pip packages, JetBrains IDEs, portable applications, and some enterprise monitoring agents; build an allowlist of SHA256 hashes for these. (2) Tune the suspicious loader list for your environment — if your org uses MSBuild for CI/CD pipelines, add MSBuild parent process + known build output paths to an exclusion. (3) Prioritize unsigned DLL loads from temp paths by non-browser processes — this subset has the highest true positive rate. (4) For Sysmon-based detection, ensure ImageLoad events are configured in your sysmon.xml — by default, Sysmon does not capture all image loads; use the '<ImageLoad>' configuration block with <onmatch='exclude'> rules for known-good publisher signatures. (5) On Linux/macOS, LD_PRELOAD and DYLD_INSERT_LIBRARIES monitoring via auditd or Endpoint Security Framework has high true-positive rates when set on non-root processes outside of /usr/lib. Tune by focusing on processes loading .so/.dylib files from /tmp, /var/tmp, or user home directories.


Hunting Queries

Hunt for unsigned DLLs loaded from non-standard paths that appear across multiple hosts. A shared malicious module deployed via lateral movement will be loaded on multiple machines — this query surfaces those by finding unsigned modules with high host-count spread, indicating campaign-level deployment.

Hunting — KQL
kql
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where FileName endswith ".dll"
| where not(FolderPath has_any ("\\Windows\\System32\\", "\\Windows\\SysWOW64\\", "\\Windows\\WinSxS\\", "\\Program Files\\", "\\Program Files (x86)\\"))
| where IsCertificateValid != true or isempty(Signer)
| summarize LoadCount=count(), DistinctProcesses=dcount(InitiatingProcessFileName), DistinctHosts=dcount(DeviceName), LoadingProcesses=make_set(InitiatingProcessFileName, 10) by FileName, FolderPath, SHA256, Signer
| where DistinctHosts > 1
| sort by DistinctHosts desc, LoadCount desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=7 Signed=false
| eval ImageLoaded=coalesce(ImageLoaded, "")
| eval IsKnownGoodDir=if(match(lower(ImageLoaded), "(\\\\windows\\\\system32\\\\|\\\\windows\\\\syswow64\\\\|\\\\windows\\\\winsxs\\\\|\\\\program files\\\\)"), 1, 0)
| where IsKnownGoodDir=0
| stats count as LoadCount, dc(Image) as DistinctProcesses, dc(host) as DistinctHosts, values(Image) as LoadingProcesses by ImageLoaded, Hashes
| where DistinctHosts > 1
| sort - DistinctHosts, - LoadCount

Hunt specifically for DLL loading from UNC network paths. This pattern is highly suspicious — legitimate software rarely loads core functionality from network shares at runtime. This can indicate an attacker using a compromised file server as a staging location for modular malware payloads, or living-off-the-land network share abuse.

Hunting — KQL
kql
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where FileName endswith ".dll"
| where FolderPath matches regex @"^\\\\\\\\[^\\]+\\\\[^\\]+\\\\"
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, FolderPath, SHA256, Signer, IsCertificateValid
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=7
| where match(ImageLoaded, "^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\")
| table _time, host, User, Image, CommandLine, ImageLoaded, Signed, SignatureStatus, Hashes
| sort - _time

Hunt for discovery and reconnaissance commands spawned by processes that also loaded suspicious DLLs from non-standard paths. Modular malware commonly uses a loader process that loads a recon module, then immediately executes discovery commands (whoami, ipconfig, nltest) — this correlation surfaces that post-load activity pattern.

Hunting — KQL
kql
let ModuleLoads = DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where FileName endswith ".dll"
| where not(FolderPath has_any ("\\Windows\\System32\\", "\\Windows\\SysWOW64\\", "\\Windows\\WinSxS\\", "\\Program Files\\", "\\Program Files (x86)\\"));
let ProcessCreations = DeviceProcessEvents
| where Timestamp > ago(7d);
ModuleLoads
| join kind=inner (ProcessCreations) on $left.InitiatingProcessId == $right.ProcessId, $left.DeviceName == $right.DeviceName
| where FileName1 in~ ("cmd.exe", "net.exe", "net1.exe", "nltest.exe", "whoami.exe", "ipconfig.exe", "systeminfo.exe", "tasklist.exe", "reg.exe", "schtasks.exe", "sc.exe")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, FileName, SHA256, FileName1, ProcessCommandLine1
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=7
| eval ImageLoaded=coalesce(ImageLoaded, "")
| eval IsKnownGoodDir=if(match(lower(ImageLoaded), "(\\\\windows\\\\system32\\\\|\\\\windows\\\\syswow64\\\\|\\\\program files\\\\)"), 1, 0)
| where IsKnownGoodDir=0
| rename Image as LoadingProcess, CommandLine as LoadingCmdLine
| eval ProcessId=ProcessId
| join type=inner ProcessId [
    search index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
    | where match(lower(Image), "(\\\\cmd\.exe|\\\\net\.exe|\\\\nltest\.exe|\\\\whoami\.exe|\\\\ipconfig\.exe|\\\\systeminfo\.exe|\\\\tasklist\.exe|\\\\reg\.exe|\\\\schtasks\.exe|\\\\sc\.exe)")
    | rename ParentProcessId as ProcessId
]
| table _time, host, User, LoadingProcess, ImageLoaded, Image, CommandLine
| sort - _time

Atomic Red Team Tests

Test 1 Load DLL from Temp Directory via rundll32
windows

Copies a benign system DLL to the user's Temp directory and uses rundll32.exe to load and invoke an export from it. This simulates the pattern used by gh0st RAT and PUNCHBUGGY where a malicious DLL is staged in a writable location and then loaded via the Windows module loader. The DLL used (msvcrt.dll) is benign — only the loading path and mechanism is simulated.

Command

powershell
copy C:\Windows\System32\msvcrt.dll %TEMP%\df00tech-test-module.dll && rundll32.exe %TEMP%\df00tech-test-module.dll,printf

Cleanup

powershell
del %TEMP%\df00tech-test-module.dll

Expected Telemetry

Sysmon Event ID 7 (ImageLoad): ImageLoaded path will be %TEMP%\df00tech-test-module.dll, Image will be C:\Windows\System32\rundll32.exe. Sysmon Event ID 1 (Process Create): rundll32.exe with command line containing the Temp path. Security Event ID 4688 if command line auditing is enabled.

Expected Detection

KQL alert fires: FolderPath contains AppData\Local\Temp, IsSuspiciousLoader=true (rundll32). SPL alert fires: IsTempPath=1, IsSuspiciousLoader=1, SuspicionScore >= 2.

Test 2 Load DLL via PowerShell Assembly.LoadFile from AppData
windows

Uses PowerShell's [System.Reflection.Assembly]::LoadFile() to load a .NET assembly (DLL) from the AppData\Roaming directory — a common technique used by Astaroth and modular .NET-based malware to load capability modules. The assembly used is a benign system DLL copied to the staging location.

Command

powershell
copy C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll $env:APPDATA\df00tech-module.dll; powershell.exe -Command "[System.Reflection.Assembly]::LoadFile('$env:APPDATA\df00tech-module.dll')"

Cleanup

powershell
Remove-Item $env:APPDATA\df00tech-module.dll -ErrorAction SilentlyContinue

Expected Telemetry

Sysmon Event ID 7: ImageLoaded will show AppData\Roaming\df00tech-module.dll loaded by powershell.exe. Sysmon Event ID 1: PowerShell process creation with LoadFile command. Sysmon Event ID 11: File creation of df00tech-module.dll in AppData\Roaming.

Expected Detection

KQL: IsTempPath=true (AppData\Roaming matches), InitiatingProcessFileName=powershell.exe. SPL: IsTempPath=1, SuspicionScore >= 1. Also triggers PowerShell anomaly detection if running concurrent with T1059.001 rules.

Test 3 Load Shared Object from /tmp via dlopen on Linux
linux

Compiles a minimal shared object (.so) in /tmp and loads it via a Python ctypes.CDLL call — simulating the RotaJakiro pattern of loading modular .so payloads from temporary locations using dlopen. The .so contains only a harmless function that writes to stdout.

Command

bash
cat > /tmp/df00tech_test_module.c << 'EOF'
#include <stdio.h>
void df00tech_init() { printf("df00tech module loaded\n"); }
EOF
gcc -shared -fPIC -o /tmp/df00tech_test_module.so /tmp/df00tech_test_module.c && python3 -c "import ctypes; lib = ctypes.CDLL('/tmp/df00tech_test_module.so'); lib.df00tech_init()"

Cleanup

bash
rm -f /tmp/df00tech_test_module.c /tmp/df00tech_test_module.so

Expected Telemetry

Auditd syscall events: openat(2) call to /tmp/df00tech_test_module.so from python3 process. Linux audit event type=EXECVE for gcc and python3. If using Falco or Sysdig: proc.name=python3 with fd.name=/tmp/*.so triggers shared lib load from tmp rule. Syslog entry if auditd is configured to monitor /tmp for file opens.

Expected Detection

Linux auditd rule '-a always,exit -F arch=b64 -S openat -F dir=/tmp -F name_suffix=.so -k shared_module_load' captures the dlopen call. Falco rule 'Load Shared Library from /tmp' fires on the ctypes.CDLL call.

Test 4 Regsvr32 Loading Unregistered DLL from User-Writable Path
windows

Uses regsvr32.exe to load a DLL from the Windows Temp directory, simulating the ATT&CK technique where regsvr32 is abused as a module loader for malicious DLLs that implement DllRegisterServer. This pattern is commonly used by commodity malware to load initial-stage payloads. The benign msvcrt.dll is used as a stand-in for the malicious DLL.

Command

powershell
copy C:\Windows\System32\msvcrt.dll C:\Windows\Temp\df00tech-reg-test.dll && regsvr32.exe /s C:\Windows\Temp\df00tech-reg-test.dll

Cleanup

powershell
del C:\Windows\Temp\df00tech-reg-test.dll

Expected Telemetry

Sysmon Event ID 7 (ImageLoad): ImageLoaded=C:\Windows\Temp\df00tech-reg-test.dll, Image=C:\Windows\System32\regsvr32.exe. Sysmon Event ID 1: regsvr32.exe with /s flag and the temp path. The /s flag suppresses the dialog box — this silence flag is itself a behavioral indicator used in malware deployment.

Expected Detection

KQL: IsTempPath=true (Windows\Temp), IsSuspiciousLoader=true (regsvr32.exe). SPL: IsTempPath=1, IsSuspiciousLoader=1, SuspicionScore >= 2. Correlation with T1218.010 (Regsvr32) detection rules will also fire.

Test 5 Load dylib from /tmp on macOS via Python ctypes
macos

Compiles a minimal .dylib in /tmp and loads it via Python ctypes on macOS — simulating the LightSpy and OceanLotus pattern of loading modular .dylib payloads from temporary locations using dlopen(). The .dylib contains a harmless initialization function.

Command

bash
cat > /tmp/df00tech_test_module.c << 'EOF'
#include <stdio.h>
void df00tech_init() { printf("df00tech dylib loaded\n"); }
EOF
cc -shared -fPIC -o /tmp/df00tech_test_module.dylib /tmp/df00tech_test_module.c && python3 -c "import ctypes; lib = ctypes.CDLL('/tmp/df00tech_test_module.dylib'); lib.df00tech_init()"

Cleanup

bash
rm -f /tmp/df00tech_test_module.c /tmp/df00tech_test_module.dylib

Expected Telemetry

macOS Endpoint Security Framework: ES_EVENT_TYPE_NOTIFY_MMAP event for the dylib mmap into python3 process address space. Unified log (log stream --predicate 'subsystem == "com.apple.dyld"') shows dylib load from /tmp. If Jamf Protect or CrowdStrike Falcon is deployed: 'Shared Library Loaded from /tmp' detection fires.

Expected Detection

macOS ESF-based detection for DYLIB loads from /tmp or /var/folders. Osquery query 'SELECT * FROM process_open_files WHERE path LIKE "/tmp/%.dylib"' surfaces the open file handle. Unified log correlation for dyld events originating from /tmp paths.

Related Detections

Tactic Hub