ID: 0xFF-0070-Suspicious_use_of_CPL_file-Win
OS: WindowsServer, WindowsEndpoint
FP Rate: Low
Tactic | Technique | Subtechnique | Technique Name |
---|---|---|---|
TA0005 - Defense Evasion | T1218 | 002 | System Binary Proxy Execution - Control Panel |
Log Provider | Event ID | Event Name | ATT&CK Data Source | ATT&CK Data Component |
---|---|---|---|---|
MicrosoftThreatProtection | ImageLoaded | Module | Module Load |
This query identifies .cpl files being loaded and verifies if the corresponding file is suspicious by looking at the signature and global prevalence.
User
Adversaries may abuse control.exe to proxy execution of malicious payloads. .cpl files loaded by control.exe are actually .dll files renamed to .cpl and can execute arbitrary code.
This detection doesn't necessarily look at executions of a .cpl file from control.exe triggered by "double clicking". Any .cpl file loaded is checked for prevalence.
Legitimate custom software might create a control panel item that is unsigned or has a low global prevalence.
Verify whether the .cpl file loaded is part of a genuine business application. If not, it should be investigated if .cpl files have been abused by an attacker to bypass detection.
DeviceImageLoad events performs heavy sampling of the telemetry. If MDE doesn't log the image load event, this detection won't trigger.
- https://attack.mitre.org/techniques/T1218/002/
- https://medium.com/falconforce/falconfriday-process-injection-and-malicious-cpl-files-0xff03-8ba1ee5da64
Language: Kusto
Platform: M365 Security
Query:
let timeframe = 2*1h;
let default_global_prevalence = 0;
let suspiciousCPLs = DeviceImageLoadEvents
| where ingestion_time() >= ago(timeframe)
// Begin environment-specific filter.
// End environment-specific filter.
| where FileName endswith ".cpl"
| summarize by SHA1
// FileProfile is case-sensitive and works on lower-case hashes.
| extend SHA1=tolower(SHA1)
| invoke FileProfile(SHA1, 1000)
| where not(ProfileAvailability =~ "Error")
// Begin environment-specific filter.
// End environment-specific filter.
| where ((isempty(Signer) or not(IsCertificateValid==1)) and coalesce(GlobalPrevalence,default_global_prevalence) < 100) or coalesce(GlobalPrevalence,default_global_prevalence) < 50;
let loadedDlls=DeviceImageLoadEvents
| where ingestion_time() >= ago(timeframe)
// FileProfile is case-sensitive and works on lower-case hashes.
| extend SHA1=tolower(SHA1)
| where SHA1 in~ ((suspiciousCPLs|project SHA1)) and ActionType =~ "ImageLoaded"
// Begin environment-specific filter.
// End environment-specific filter.
;
loadedDlls
| join kind=leftouter suspiciousCPLs on SHA1
// Begin environment-specific filter.
// End environment-specific filter.
Version | Date | Impact | Notes |
---|---|---|---|
1.6 | 2024-06-28 | minor | Modified the usage of FileProfile to exclude results if the call to the FileProfile API has failed. |
1.5 | 2023-01-03 | minor | Lowered the case of hashes that are fed to the FileProfile function due to case sensitivity. |
1.4 | 2022-11-01 | minor | Use default_global_prevalence variable to allow customizing handling of empty GlobalPrevalence |
1.3 | 2022-07-25 | minor | Added more filtering options. |
1.2 | 2022-05-20 | minor | Updated the considerations and blindspots information. |
1.1 | 2022-02-22 | minor | Use ingestion_time for event selection and include de-duplication logic. |
1.0 | 2021-02-16 | major | Initial version. |