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).
Known false positives
- Administrators might share MSC files using SharePoint or other file sharing services. These might have to by filtered out.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Stealth |
References
Telemetry coverage
Rule body
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."
);
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."
);
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."
);
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."
);
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)."
);
Let binding: SuspiciousMscFiles
let SuspiciousMscFiles = (
union MscRenamedFromCrDownload, MscWrittenByBrowser, MscInDownloadsFolder, MscDecompressed, MscMOTW
| distinct FolderPath=tolower(FolderPath), DeviceId, FileOriginUrl, MscSHA1=SHA1, SuspiciousReason, MscCreatedBy=InitiatingProcessFolderPath, MscCreatedByCommandLine=InitiatingProcessCommandLine
);
Stage 1: source
let MscRenamedFromCrDownload
Stage 2: source
let MscWrittenByBrowser
Stage 3: source
let MscInDownloadsFolder
Stage 4: source
let MscDecompressed
Stage 5: source
let MscMOTW
Stage 6: source
let SuspiciousMscFiles
Stage 7: source
DeviceProcessEvents
Stage 8: where
where ...
Stage 9: where
where ActionType =~ "ProcessCreated"
Stage 10: where
where FileName =~ "mmc.exe"
Stage 11: extend
extend ParsedCommandLine
Stage 12: where
where ParsedCommandLine contains ".msc"
Stage 13: extend (3 consecutive steps)
extend MscFile
Stage 14: kusto:lookup
lookup kind=inner (SuspiciousMscFiles) on DeviceId, MscFile, FolderPath
Stage 15: project-reorder
project-reorder
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActionType | eq |
| field:"ActionType" kind:eq |
FileName | ends_with |
| field:"file_name" kind:ends_with value:".msc" |
FileName | eq |
| field:"file_name" kind:eq value:"mmc.exe" |
FileOriginUrl | is_not_null | field:"FileOriginUrl" kind:is_not_null | |
FolderPath | contains |
| field:"Image" kind:contains |
FolderPath | regex_match |
| field:"Image" kind:regex_match value:"((?i)[^=|\/]*?AppData\Local\Temp\(7z.........\|wz....\|Temp\d{1,3}_\w+)\b[^( ;)|]*)" |
InitiatingProcessFileName | in |
| field:"parent_process_name" kind:in |
ParsedCommandLine | contains |
| field:"ParsedCommandLine" kind:contains value:".msc" |
PreviousFileName | ends_with |
| field:"PreviousFileName" kind:ends_with value:".crdownload" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ParsedCommandLine | extend |
MscFile | extend |