Mutual Exclusion
Adversaries may constrain execution or actions based on the presence of a mutex associated with malware. A mutex is a locking mechanism used to synchronize access to a resource — only one thread or process can hold a given mutex at a time. By creating a uniquely named system mutex at startup, malware checks whether a prior instance is already running: if the mutex already exists, the new instance silently exits, preventing duplicate infections that could increase analyst visibility. Mutex names may be hard-coded strings (Embargo ransomware uses "LoadUpOnGunsBringYourFriends"; SUNSPOT uses a GUID string; Gazer uses "{531511FA-190D-5D85-8A4A-279F2F592CC7}"), machine-derived (LockBit 3.0 hashes the host MachineGUID value), or computed from the binary itself (GrimAgent uses the last 64 bytes of its PE file). In Linux environments, malware such as BPFDoor acquires an exclusive file lock on a runtime file — typically in /var/run/ — achieving the same single-instance effect without Windows API calls. Mutex-based execution guardrails indicate operational maturity: they reduce noise from redundant infections and help adversaries maintain stealth during long-dwell campaigns.
let KnownMalwareMutexes = dynamic([
"LoadUpOnGunsBringYourFriends", // Embargo ransomware (Cyble 2024)
"mymutex", // GrimAgent default fallback
"{12d61a41-4b74-7610-a4d8-3028d2f56395}", // SUNSPOT (SolarWinds intrusion)
"{531511FA-190D-5D85-8A4A-279F2F592CC7}", // Gazer backdoor (Turla)
"I_am_an_unique_mutex",
"Global\\TermService_alive",
"Global\\MS_HIDDENCLK_R"
]);
let SuspiciousProcessPaths = dynamic([
"\\AppData\\Roaming\\",
"\\AppData\\Local\\Temp\\",
"\\Users\\Public\\",
"\\ProgramData\\",
"\\Windows\\Temp\\",
"\\Recycle"
]);
let TrustedSystemProcesses = dynamic([
"svchost.exe", "services.exe", "lsass.exe", "MsMpEng.exe",
"SenseIR.exe", "msiexec.exe", "TiWorker.exe", "TrustedInstaller.exe"
]);
// Branch 1: Direct mutex telemetry via MDE enhanced ETW (Defender for Endpoint P2)
let MutexEvents = DeviceEvents
| where Timestamp > ago(24h)
| where ActionType has "Mutex" or ActionType has "Mutant"
| extend MutexName = coalesce(
tostring(parse_json(AdditionalFields).MutexName),
tostring(parse_json(AdditionalFields).ObjectName),
tostring(parse_json(AdditionalFields).Name)
)
| where isnotempty(MutexName)
| where MutexName has_any (KnownMalwareMutexes)
or (
MutexName matches regex @"^\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\}$"
and not (InitiatingProcessFileName in~ (TrustedSystemProcesses))
and InitiatingProcessFolderPath has_any (SuspiciousProcessPaths)
)
or (
MutexName matches regex @"^Global\\\\[0-9a-fA-F]{32}$"
and InitiatingProcessFolderPath has_any (SuspiciousProcessPaths)
)
| project
Timestamp,
DeviceName,
AccountName = InitiatingProcessAccountName,
ProcessName = InitiatingProcessFileName,
ProcessPath = InitiatingProcessFolderPath,
ProcessCommandLine = InitiatingProcessCommandLine,
MutexName,
ParentProcess = InitiatingProcessParentFileName,
DetectionBranch = "MutexAPIEvent";
// Branch 2: Linux-style lock file creation in /var/run/ or /var/lock/ by non-system processes
// Matches BPFDoor (/var/run/initd.lock) and RedXOR patterns
let LockFileEvents = DeviceFileEvents
| where Timestamp > ago(24h)
| where ActionType == "FileCreated"
| where FolderPath startswith "/var/run/" or FolderPath startswith "/var/lock/"
| where FileName endswith ".lock" or FileName endswith ".pid" or FileName endswith ".run"
| where not (InitiatingProcessFileName in~ (
"systemd", "init", "chronyd", "sshd", "crond", "cron",
"rsyslogd", "dbus-daemon", "NetworkManager", "nginx",
"apache2", "httpd", "mysqld", "postgres", "postfix",
"auditd", "dockerd", "containerd", "kubelet"
))
| where not (
InitiatingProcessFolderPath startswith "/usr/sbin/"
or InitiatingProcessFolderPath startswith "/usr/bin/"
or InitiatingProcessFolderPath startswith "/usr/lib/"
or InitiatingProcessFolderPath startswith "/lib/systemd/"
or InitiatingProcessFolderPath startswith "/sbin/"
or InitiatingProcessFolderPath startswith "/bin/"
)
| project
Timestamp,
DeviceName,
AccountName = InitiatingProcessAccountName,
ProcessName = InitiatingProcessFileName,
ProcessPath = InitiatingProcessFolderPath,
ProcessCommandLine = InitiatingProcessCommandLine,
MutexName = strcat(FolderPath, "/", FileName),
ParentProcess = InitiatingProcessParentFileName,
DetectionBranch = "LinuxLockFile";
union MutexEvents, LockFileEvents
| sort by Timestamp desc Data Sources
Required Tables
False Positives
- Legitimate .NET and Java applications using GUID-format named mutexes for single-instance enforcement (e.g., JetBrains IDEs, Adobe products)
- Software installers (NSIS, Inno Setup, WiX-based) that create temporary GUID-named mutexes during installation from user temp directories
- Package managers and system daemons (apt, yum, pip) creating lock files in /var/run/ during update operations
- Database engines (MySQL, PostgreSQL, MongoDB) creating PID files in /var/run/ at daemon startup
- Container runtimes (dockerd, containerd) creating runtime lock and PID files in /var/run/docker/ or /var/run/containerd/
References (10)
- https://attack.mitre.org/techniques/T1480/002/
- https://learn.microsoft.com/en-us/dotnet/standard/threading/mutexes
- https://www.deepinstinct.com/blog/bpfdoor-malware-evolves-stealthy-sniffing-backdoor-ups-its-game
- https://intezer.com/blog/malware-analysis/new-linux-backdoor-redxor-likely-operated-by-chinese-nation-state-actor/
- https://www.sans.org/blog/looking-at-mutex-objects-for-malware-discovery-indicators-of-compromise/
- https://isc.sans.edu/diary/How+Malware+Generates+Mutex+Names+to+Evade+Detection/19429/
- https://www.crowdstrike.com/blog/sunspot-malware-technical-analysis/
- https://blog.cyble.com/2024/05/27/embargo-ransomware-new-rust-based-ransomware-group-emerges/
- https://www.justice.gov/opa/pr/joint-cybersecurity-advisory-lockbit-30-ransomware
- https://learn.microsoft.com/en-us/sysinternals/downloads/handle
Unlock Pro Content
Get the full detection package for T1480.002 including response playbook, investigation guide, and atomic red team tests.