Detection rules › Kusto
Suspicious MSC File Launched
The query searches for suspicious MSC files that are launched on the system. The following types of suspicious files are detected: MSC files downloaded by web browsers, MSC files in the Downloads folder, MSC files extracted from ZIP files, and MSC files with Mark Of The Web (MOTW).
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | T1566 Phishing |
| Stealth | T1218.014 System Binary Proxy Execution: MMC |
References
Event coverage
| Provider | Event/ActionType | Title |
|---|---|---|
| Sysmon | Event ID 1 | Process creation |
| Sysmon | Event ID 11 | FileCreate |
| Security-Auditing | Event ID 4663 | An attempt was made to access an object. |
| Security-Auditing | Event ID 4688 | A new process has been created. |
| Defender-DeviceFileEvents | FileCreated | File created |
| Defender-DeviceFileEvents | FileRenamed | File renamed |
| Defender-DeviceProcessEvents | ProcessCreated | Process created |
Rule body kusto
let timeframe = 2*1h;
let RegexValidateTempZipPath = @"((?i)[^=|\/]*?AppData\\Local\\Temp\\(7z.........\\|wz....\\|Temp\d{1,3}_\w+)\b[^( ;)|]*)";
let MscRenamedFromCrDownload=(
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed"
| where FileName endswith ".msc"
| where PreviousFileName endswith ".crdownload"
| extend SuspiciousReason="MSC file downloaded by web browser."
);
let MscWrittenByBrowser=(
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "brave.exe", "opera.exe", "vivaldi.exe", "iexplore.exe", "msedgewebview2.exe", "firefox.exe")
| extend SuspiciousReason="MSC file downloaded by web browser."
);
let MscInDownloadsFolder=(
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where FolderPath contains @"\downloads\"
| extend SuspiciousReason="MSC file downloaded by web browser."
);
let MscDecompressed=(
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where InitiatingProcessFileName in~ ("7zfm.exe", "7zg.exe", "7z.exe", "winzip64.exe", "winrar.exe", "winzip.exe")
or FolderPath matches regex RegexValidateTempZipPath
or FolderPath contains @".zip\"
| extend SuspiciousReason="MSC file extracted from zip file."
);
let MscMOTW=(
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where isnotempty(FileOriginUrl)
| extend SuspiciousReason="MSC file with Mark Of The Web (MOTW)."
);
let SuspiciousMscFiles=(
union MscRenamedFromCrDownload, MscWrittenByBrowser, MscInDownloadsFolder, MscDecompressed, MscMOTW
| distinct FolderPath=tolower(FolderPath), DeviceId, FileOriginUrl, MscSHA1=SHA1, SuspiciousReason, MscCreatedBy=InitiatingProcessFolderPath, MscCreatedByCommandLine=InitiatingProcessCommandLine
);
DeviceProcessEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "ProcessCreated"
| where FileName =~ "mmc.exe"
| extend ParsedCommandLine=parse_command_line(ProcessCommandLine, "windows")
// Look for process creations of mmc.exe where the .msc file is on the command-line, indicating that the user clicked on the .msc file.
| where tostring(ParsedCommandLine) contains ".msc"
// When a .msc file is opened in MMC, the file path is passed as an argument to MMC.
// Based on testing this is the first argument in the command line. In some cases a command-line switch /32 is passed as the first argument
// and the file path is the second argument. This is handled by the iif statement below.
| extend MscFile=ParsedCommandLine[1]
| extend MscFile=iif(MscFile startswith "/", ParsedCommandLine[2], MscFile)
| extend MscFile=tolower(MscFile)
| lookup kind=inner SuspiciousMscFiles on DeviceId, $left.MscFile == $right.FolderPath
| project-reorder Timestamp, DeviceId, DeviceName, SuspiciousReason, MscFile, MscCreatedBy, MscCreatedByCommandLine, MscSHA1
// Begin environment-specific filter.
// End environment-specific filter.
Stages and Predicates
Parameters
let timeframe = 2*1h;
Let binding: RegexValidateTempZipPath
let RegexValidateTempZipPath = @"((?i)[^=|\/]*?AppData\\Local\\Temp\\(7z.........\\|wz....\\|Temp\d{1,3}_\w+)\b[^( ;)|]*)";
Let binding: MscRenamedFromCrDownload
let MscRenamedFromCrDownload = (
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed"
| where FileName endswith ".msc"
| where PreviousFileName endswith ".crdownload"
| extend SuspiciousReason="MSC file downloaded by web browser."
);
Derived from timeframe.
Let binding: MscWrittenByBrowser
let MscWrittenByBrowser = (
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "brave.exe", "opera.exe", "vivaldi.exe", "iexplore.exe", "msedgewebview2.exe", "firefox.exe")
| extend SuspiciousReason="MSC file downloaded by web browser."
);
Derived from timeframe.
Let binding: MscInDownloadsFolder
let MscInDownloadsFolder = (
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where FolderPath contains @"\downloads\"
| extend SuspiciousReason="MSC file downloaded by web browser."
);
Derived from timeframe.
Let binding: MscDecompressed
let MscDecompressed = (
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where InitiatingProcessFileName in~ ("7zfm.exe", "7zg.exe", "7z.exe", "winzip64.exe", "winrar.exe", "winzip.exe")
or FolderPath matches regex RegexValidateTempZipPath
or FolderPath contains @".zip\"
| extend SuspiciousReason="MSC file extracted from zip file."
);
Derived from timeframe, RegexValidateTempZipPath.
Let binding: MscMOTW
let MscMOTW = (
DeviceFileEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "FileRenamed" or ActionType == "FileCreated"
| where FileName endswith ".msc"
| where isnotempty(FileOriginUrl)
| extend SuspiciousReason="MSC file with Mark Of The Web (MOTW)."
);
Derived from timeframe.
Let binding: SuspiciousMscFiles
let SuspiciousMscFiles = (
union MscRenamedFromCrDownload, MscWrittenByBrowser, MscInDownloadsFolder, MscDecompressed, MscMOTW
| distinct FolderPath=tolower(FolderPath), DeviceId, FileOriginUrl, MscSHA1=SHA1, SuspiciousReason, MscCreatedBy=InitiatingProcessFolderPath, MscCreatedByCommandLine=InitiatingProcessCommandLine
);
Derived from MscRenamedFromCrDownload, MscWrittenByBrowser, MscInDownloadsFolder, MscDecompressed, MscMOTW.
Stage 1: source
DeviceProcessEvents
Stage 2: where
| where ingestion_time() >= ago(timeframe)
Stage 3: where
| where ActionType == "ProcessCreated"
Stage 4: where
| where FileName =~ "mmc.exe"
Stage 5: extend
| extend ParsedCommandLine=parse_command_line(ProcessCommandLine, "windows")
Stage 6: where
| where tostring(ParsedCommandLine) contains ".msc"
Stage 7: extend (3 consecutive steps)
| extend MscFile=ParsedCommandLine[1]
| extend MscFile=iif(MscFile startswith "/", ParsedCommandLine[2], MscFile)
| extend MscFile=tolower(MscFile)
Stage 8: kusto:lookup
| lookup kind=inner SuspiciousMscFiles on DeviceId, $left.MscFile == $right.FolderPath
Stage 9: project-reorder
| project-reorder Timestamp, DeviceId, DeviceName, SuspiciousReason, MscFile, MscCreatedBy, MscCreatedByCommandLine, MscSHA1
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
ActionType | eq |
|
FileName | eq |
|
ParsedCommandLine | contains |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
ParsedCommandLine | extend |
MscFile | extend |