VOLTA / VOLTA-AUTODOXER Infostealer
Executive Summary
VOLTA is a Windows infostealer that harvests browser credentials, cookies and payment cards, cryptocurrency wallet seed phrases, Discord, Telegram, Steam and Roblox sessions, Microsoft OAuth tokens, SSH and cloud-provider keys, saved Wi-Fi profiles and screenshots. It then uses stolen sessions to enrich the victim profile (Gmail receipt searches to confirm a home address, UberEats and DoorDash order history, a live Roblox inventory valuation), assembles the result locally as Identity_Report.txt, POSTs it to OpenRouter under a "forensic intelligence analyst" system prompt, and saves the model output as AI_Analysis.txt. Both files leave in volta_dox.zip. The executable then deletes itself.
Talos describes a builder model: the customer supplies a Telegram channel, API keys and settings, and the builder compiles a binary per order. The default model is anthropic/claude-opus-4.6, with a fallback chain to moonshotai/kimi-k2 and then google/gemini-2.5-flash when a response looks like a refusal.
Defensive angle. Every network endpoint Talos observed is a third-party service, so there is nothing to blocklist. Durable detection comes from (1) host artifacts the stealer writes, (2) an unusual process talking to openrouter.ai and rolimons.com, (3) Chrome launched with --headless by an unexpected parent, and (4) fast credential and session revocation after any hit, because the implant deletes itself and the log file may be the only evidence.
Defender priority: treat any hit as a full credential, session and wallet compromise. Preserve %APPDATA%\volta_debug.txt before reimaging, revoke tokens first, and never block openrouter.ai or rolimons.com through an IOC prevent rule: both are legitimate services used by ordinary customers.
Confidence limits: one primary source (Talos). The SHA-256 is single-sourced and ships at detect. Talos does not describe initial access, so delivery is an open gap in this pack.
Source Review & Web Hunter Notes
| Tier | Source | Key finding | Carry forward | Snapshot |
|---|---|---|---|---|
| 1 | Cisco Talos, "Appraisal by AI: Model-driven victim prioritization in the VOLTA infostealer" (2026-10-31) | Full capability, workflow, model chain, exfil stages, countermeasures, sample hash and filenames | yes | 01-talos-volta.txt |
| 1 | Google Security Blog, Improving the security of Chrome cookies on Windows | App-Bound Encryption design, ApplicationBoundEncryptionEnabled policy; context for the ABE bypass Talos reports | partial | 02-google-chrome-abe.txt |
| 2 | MITRE ATT&CK T1555.003 Credentials from Web Browsers | Technique definition and mitigations M1027, M1021, M1051, M1018, M1017 | partial | 03-mitre-t1555-003.txt |
| 2 | MITRE ATT&CK T1539 Steal Web Session Cookie | Technique definition and mitigations M1047, M1032, M1021, M1054, M1051, M1017 | partial | 04-mitre-t1539.txt |
| 1 | Microsoft Learn, attack surface reduction rules reference | Rule GUID and behavior for the prevalence, age and trusted-list executable rule | partial | 05-ms-asr-rules.txt |
| 1 | Microsoft Learn, Revoke-MgUserSignInSession | Cmdlet used to invalidate refresh tokens and session cookies for a user | partial | 06-ms-revoke-signin.txt |
Research notes
- Single primary source. A web search on 2026-11-01 for VOLTA, VOLTA-AUTODOXER and the OpenRouter angle returned no independent coverage of this family. Nothing here is corroborated by a second vendor, so no indicator ships above detect and no row is action=prevent.
- Fetch method. The Talos page was fetched directly and saved as visible article text. A summarizing fetch tool was not used for indicator values because it can corrupt hash characters. Every atomic value in this pack was copied from the saved snapshot by script.
- Name discipline. Only names the source uses appear as threat names: VOLTA, VOLTA-AUTODOXER and CAIRN. Talos also mentions an unrelated implant named CLOSEDQUORUM; nothing from it is borrowed.
- Hostile content check. None of the fetched sources contained instructions directed at the reader or the pipeline.
Hunt Brief & Attack Chain
Hypotheses
| # | Hypothesis | MITRE | Telemetry | Confidence | Queries |
|---|---|---|---|---|---|
| H1 | A host executed or wrote the published VOLTA sample or one of its build filenames. | T1204.002 | Process creation with command line and hash; executable file writes | HIGH | Q1 |
| H2 | A host wrote one of the three VOLTA staged exfiltration archives. | T1560 | Archive file writes | HIGH | Q2 |
| H3 | A single non-browser process resolved both openrouter.ai and rolimons.com. | T1071.001, T1567 | DNS lookup with requesting process | HIGH | Q4 |
| H4 | A non-browser process resolved openrouter.ai. | T1071.001 | DNS lookup with requesting process | MEDIUM | Q3 |
| H5 | Chrome or Edge was launched headless by an unexpected parent to reach browser secrets. | T1555.003, T1539 | Process creation with command line and parent | MEDIUM | Q5 |
| H6 | A non-browser process resolved the Telegram Bot API host (inferred exfil channel). | T1567 | DNS lookup with requesting process | LOW | Q6 |
| H7 | A randomly named 12 character executable ran from a user-writable path. | T1036.005 | Process creation with command line, path and hash | LOW | Q7 |
Attack chain (as reported by Talos)
| Step | Behavior | Telemetry (CrowdStrike / SentinelOne / Defender) | Hunt angle |
|---|---|---|---|
| 1 | Initial access: not described by Talos | outside this report | GAP see section 15 |
| 2 | Per-customer binary built from a six-slot template (Telegram channel, keys, settings); credentials in the slots are encrypted with a key derived from two constants in the same binary | Executable file written; process creation (CrowdStrike: PeFileWritten, NewExecutableWritten, ProcessRollup2. SentinelOne: File Creation, Process Creation. Defender: DeviceFileEvents, DeviceProcessEvents) | Q1, Q7 |
| 3 | Chrome App-Bound Encryption bypass for credential and token theft; Talos recommends controlling --headless launches | Process creation with command line and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | Q5 |
| 4 | Bulk collection: browsers, Firefox, Thunderbird, Outlook, Slack, Steam, Battle.net, Discord, Telegram, Roblox, SSH and cloud config (gcloud, OpenVPN, Hide.me), wallets with an inline vault cracker, Wi-Fi profiles via WlanGetProfileList, screenshots | File reads and API calls: no generic endpoint telemetry | GAP section 15 |
| 5 | Enrichment with stolen sessions: Gmail receipt search, UberEats and DoorDash order history, Discord profile, Rolimons inventory valuation | DNS lookup with requesting process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents DNS action type, name inside AdditionalFields) | Q4; the SaaS side is outside endpoint telemetry (N4) |
| 6 | Identity_Report.txt assembled, serialized to JSON and POSTed to OpenRouter chat completions; response saved as AI_Analysis.txt | DNS lookup with requesting process; outbound connection (CrowdStrike: DnsRequest, NetworkConnectIP4. SentinelOne: DNS Resolved, IP Connect. Defender: DeviceNetworkEvents) | Q3, Q4 |
| 7 | Packaging and exfiltration in up to three stages: volta_log.zip, volta_dox.zip, volta_doxnet.zip | Archive file written (CrowdStrike: ZipFileWritten. SentinelOne: File Creation. Defender: DeviceFileEvents FileCreated) | Q2, Q6 |
| 8 | Self-deletion; %APPDATA%\volta_debug.txt harvest log may remain | File deletion: not covered by a verified Falcon event in this pack | PARTIAL N1, N2 |
Consolidated IOC Table
| Type | Value | Confidence | Action | Context |
|---|---|---|---|---|
| sha256 | 57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279 | medium | detect | Talos sample (PE32+ x86-64, PE timestamp 2026-08-17, first seen 2026-10-11). Single source. One build of a builder product. |
| filename | 9BY0tjwOc3ut.exe | medium | hunt | Executable name of the sample; random per build |
| filename | yLP9m5J3i2Aw.exe | medium | hunt | Second executable name of the sample; random per build |
| path | %APPDATA%\volta_debug.txt | high | hunt | Timestamped harvest log; records what was collected and whether the LLM call succeeded. Preserve for forensics. |
| filename | Identity_Report.txt | medium | hunt | Assembled victim evidence bundle. Generic name, so pair with the other artifacts. |
| filename | AI_Analysis.txt | medium | hunt | Model output. Generic name, so pair with the other artifacts. |
| filename | volta_log.zip | high | hunt | Exfil stage 1, after the stealer run |
| filename | volta_dox.zip | high | hunt | Exfil stage 2, after the AI call (contains Identity_Report.txt and AI_Analysis.txt) |
| filename | volta_doxnet.zip | high | hunt | Exfil stage 3, if network enrichment produced anything |
| domain | openrouter.ai | low | detect (low severity) | LEGITIMATE third-party service. Endpoint path /api/v1/chat/completions. Signal is the calling process, never the domain. Never prevent. |
| domain | rolimons.com | low | detect (low severity) | LEGITIMATE third-party service. Roblox inventory valuation lookup. Never prevent. |
| string | anthropic/claude-opus-4.6, moonshotai/kimi-k2, google/gemini-2.5-flash | low | hunt | Model identifiers in the request body and fallback chain. Visible only with TLS inspection; not an endpoint indicator. |
| string | User-Agent Mozilla/5.0 (bare) on requests to OpenRouter | low | hunt | Talos: hand-assembled JSON, no SDK, generic UA. Proxy-log signal only. |
There is no attacker-owned infrastructure to list. The two domains are shipped at detect with low severity so they raise context rather than block customers. Domain and path values are shown fanged here; Talos defanged them in the source.
Affected Surface & Telemetry Matrix
| Surface | Telemetry (plain terms, then platforms) | Priority | Gap risk |
|---|---|---|---|
| Windows endpoints (user context) | Process creation with command line, path, parent and hash (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | CRITICAL | Low |
| Windows file writes (archives, executables) | Executable or archive written (CrowdStrike: NewExecutableWritten, PeFileWritten, ZipFileWritten. SentinelOne: File Creation. Defender: DeviceFileEvents) | HIGH | Medium: plain text files such as the harvest log have no verified Falcon write event |
| DNS and egress | DNS lookup with requesting process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents, DNS action type) | HIGH | Medium: encrypted DNS on the endpoint blinds it; proxy logs are the second source |
| Browser secret stores | No generic file-read event for credential databases in endpoint telemetry | HIGH | High: handled by launch-control (Q5) and hardening |
| SaaS and identity (Entra ID, Google, Discord, food delivery) | Sign-in and audit logs of each service | CRITICAL | Outside endpoint telemetry; stolen tokens are used from the victim machine first, then possibly elsewhere |
| Crypto wallets, SSH and cloud keys on disk | No endpoint event for reads; file inventory only | HIGH | Outside endpoint telemetry; rotate on any hit |
| Web proxy / TLS inspection | Destination host, URL path, User-Agent, request body model strings | MEDIUM | Medium: body inspection needs TLS decryption |
| macOS / Linux | Not reported. Talos describes a Windows implant only. | LOW | Not assessed |
ATT&CK Mapping
| Tactic | Technique | Observed behavior | Query or control |
|---|---|---|---|
| Credential Access | T1555.003 Credentials from Web Browsers | Chromium, Firefox, Thunderbird, Outlook profile theft; App-Bound Encryption bypass | Q5; hardening M1027, M1021, M1051, M1018, M1017 |
| Credential Access | T1539 Steal Web Session Cookie | Cookies and Discord, Telegram, Steam, Roblox, Microsoft OAuth tokens | Q5; M1047, M1032, M1054; token revocation playbook |
| Credential Access | T1555 Credentials from Password Stores | Saved Wi-Fi keys via WlanGetProfileList; wallet vaults | Gap (API call, no endpoint event) |
| Credential Access | T1110.002 Password Cracking | Embedded cracker run against wallet vaults | Gap (in process) |
| Credential Access | T1552 Unsecured Credentials | SSH keys, gcloud, OpenVPN and Hide.me configs | Rotation checklist |
| Collection | T1113 Screen Capture | Screenshots | Gap |
| Collection | T1114.002 Remote Email Collection | Gmail searched for purchase receipts with stolen tokens | N4 (SaaS audit) |
| Defense Evasion | T1550.001 Application Access Token | Stolen sessions reused for enrichment | N4 |
| Collection | T1560 Archive Collected Data | volta_log, volta_dox, volta_doxnet archives | Q2 |
| Command and Control | T1071.001 Web Protocols | HTTPS POST to OpenRouter and Rolimons lookup | Q3, Q4 |
| Exfiltration | T1567 Exfiltration Over Web Service | Staged archives to the customer Telegram channel (channel use per Talos; transport host not published) | Q6 (inferred) |
| Defense Evasion | T1070.004 File Deletion | Self-deleting executable | N1, N2 |
| Defense Evasion | T1036.005 Match Legitimate Name or Location | Random 12 character filenames | Q1, Q7 |
Native Audit-Log Hunts
| ID | Source | Hunt | Why |
|---|---|---|---|
| N1 | Endpoint file inventory (PowerShell) | Search user profiles for volta_debug.txt, Identity_Report.txt, AI_Analysis.txt and volta_*.zip. Read-only command in playbook P4. | The only way to see plain text artifacts without a verified Falcon write event. The harvest log can survive after the self-delete. |
| N2 | Sysmon | Event ID 11 (FileCreate) where TargetFilename ends in the artifact names above; Event ID 1 where Image or CommandLine matches the build filenames or Chrome with --headless and a non-browser ParentImage. | Closes the text-file gap and mirrors Q1, Q2 and Q5 where Sysmon is deployed. |
| N3 | Web proxy / secure web gateway | Requests to host openrouter.ai, path /api/v1/chat/completions, with a bare Mozilla/5.0 User-Agent from servers or user subnets that have no approved LLM use. With TLS inspection, search request bodies for the three model identifiers. | The LLM POST is the one step with a rich network signature. Hand-assembled JSON and a generic User-Agent are reported by Talos. |
| N4 | Entra ID and Google Workspace audit | After any endpoint hit: sign-ins and token use for the affected user from new IPs or user agents, mailbox search activity for receipt senders, and new OAuth consents. (Inference from the stolen-session behavior Talos describes; thresholds are tenant specific.) | Stolen Microsoft OAuth tokens and Gmail sessions are reused by the stealer and may be reused later by the operator. |
| N5 | Chrome Enterprise policy report | Confirm ApplicationBoundEncryptionEnabled is not set to 0 on managed browsers (playbook P1). | A disabled policy removes the protection Talos says VOLTA works to bypass. |
Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL
Use your tenant's own address. SentinelOne does not document a link that pre-fills a query, so each "Copy & open SentinelOne" button copies the query and opens this console: paste it into PowerQuery.
Pick your portal. Microsoft documents a Share link in advanced hunting but not its URL format, so each "Copy & open Defender" button copies the query and opens Advanced hunting: paste it into the editor.
Run Q1, Q2 and Q4 first: they are the high-fidelity hits. Q3, Q5, Q6 and Q7 are behavioral and need a 30 day baseline before alerting. Queries Q3, Q4 and Q6 match legitimate services by design and are hunts or detects only. The window is set with the console time picker; each card records the intended LOOKBACK.
Looks for: The single SHA-256 and the two executable names Talos published for one build. Because VOLTA is a builder product, every customer build is a different binary, so a miss proves little. A hit is a confirmed sample.
Known limitations and deployment notes
- PowerQuery: A renamed build with a different hash is not caught; the filenames are random per build.
- PowerQuery assumes: tgt.file.path holds the full path, so a substring match on the build filename finds the written file.
- PowerQuery assumes: Hash fields are populated on this tenant for both event types.
- KQL – Defender XDR: The executable-write half of the CQL (a build written to disk but never run) is not covered by this query.
- KQL – Defender XDR: A hash match depends on SHA256 being populated in DeviceProcessEvents.
- KQL – Defender XDR assumes: SHA256 is populated for the created process; where it is not, only the filename branch can match.
// HUNT: VOLTA published sample hash or build filenames executing or written // MITRE: T1204.002, T1036.005 // CONF: high | FP: low | COST: low | REQUIRES: ProcessRollup2, PeFileWritten, NewExecutableWritten // SOURCE: Talos 2026-10-31 "Sample details" table (single source, so detect only) // FALSE POSITIVES: none expected for the hash; the filenames are random per build // LOOKBACK: 30d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2|PeFileWritten|NewExecutableWritten)$/ | SHA256HashData="57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279" OR FileName=/^(9BY0tjwOc3ut\.exe|yLP9m5J3i2Aw\.exe)$/i | table([@timestamp, ComputerName, UserName, #event_simpleName, ContextBaseFileName, ParentBaseFileName, FileName, ImageFileName, TargetFileName, CommandLine, SHA256HashData, aid], limit=max)
6 required fields · View requirements
Required telemetry
- Process Creation
- File Creation
Required fields
event.type: Event typeevent.time: Event timetgt.process.name: Created process nametgt.process.image.sha256: Created process hashtgt.file.path: Written file pathtgt.file.sha256: Written file hash
Recommended fields
src.process.name: Creator process
Optional fields
tgt.process.cmdline: Command line
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type in ('Process Creation', 'File Creation')
| limit 5
| columns event.type, event.time, tgt.process.name, tgt.process.image.sha256, tgt.file.path, tgt.file.sha256// HUNT: VOLTA published sample hash or build filenames executing or written
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1204.002, T1036.005
// CONF: high | FP: low
// FALSE POSITIVES: none expected for the hash; the filenames are random per build
// EQUIVALENCE: equivalent-with-schema-assumptions - Same indicator set: the published sample hash or either build filename, on a process start or a file write. A process start maps to Process Creation and the executable write maps to File Creation. contains and in:anycase are case-insensitive, which reproduces the CQL /i intent.
// REQUIRES: SentinelOne Process Creation and File Creation events with hash population
// TUNING: None expected for the hash. The two filenames are random per build, so treat a filename-only hit as a lead to confirm by hash.
// LOOKBACK: 30d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A renamed build with a different hash is not caught; the filenames are random per build.
// VALIDATION LEVEL: static-reviewed
event.type in ('Process Creation', 'File Creation')
(tgt.process.image.sha256 in:anycase ('57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279') or tgt.file.sha256 in:anycase ('57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279') or tgt.process.name in:anycase ('9BY0tjwOc3ut.exe', 'yLP9m5J3i2Aw.exe') or tgt.file.path contains ('9BY0tjwOc3ut.exe', 'yLP9m5J3i2Aw.exe'))
| columns event.time, endpoint.name, agent.uuid, src.process.user, event.type, src.process.name, tgt.process.name, tgt.process.cmdline, tgt.file.path, tgt.process.image.sha256, tgt.file.sha256
| limit 1000Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameSHA256: Created process hash
Recommended fields
InitiatingProcessFileName: Initiating process
Optional fields
SHA1: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot when you hold one.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, SHA256 | take 5
// HUNT: VOLTA published sample hash or build filenames executing or written
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1204.002, T1036.005
// CONF: high | FP: low
// FALSE POSITIVES: none expected for the hash; the filenames are random per build
// EQUIVALENCE: telemetry-gap - Partial pivot: the process-start half of the CQL on one table. The executable-write half would need a second table, and SHA256 is often unpopulated in DeviceProcessEvents, so the hash match may return nothing on a healthy tenant while the filename match still works.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: None expected for the hash. Confirm any filename-only hit by hash.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 30d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The executable-write half of the CQL (a build written to disk but never run) is not covered by this query. A hash match depends on SHA256 being populated in DeviceProcessEvents.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where SHA256 =~ "57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279" or FileName in~ ("9BY0tjwOc3ut.exe", "yLP9m5J3i2Aw.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: An archive named for one of the three exfiltration stages Talos describes: after the stealer run (volta_log.zip), after the AI call (volta_dox.zip) and after network enrichment (volta_doxnet.zip). The match is on the basename so there is no path to escape.
Known limitations and deployment notes
- PowerQuery: A renamed archive is not caught.
- PowerQuery assumes: tgt.file.path holds the full path of the written file.
- KQL – Defender XDR: A renamed archive is not caught.
- KQL – Defender XDR assumes: A new file is recorded with ActionType FileCreated.
// HUNT: VOLTA staged exfiltration archives written to disk // MITRE: T1560, T1074.001 // CONF: high | FP: low | COST: low | REQUIRES: ZipFileWritten // SOURCE: Talos 2026-10-31 (figure 8 and exfil description) // FALSE POSITIVES: none expected; the volta_ prefix is specific to this family // NOTE: the builder is customer-configured, so a renamed archive will not match. Treat a miss as unproven. // LOOKBACK: 30d #event_simpleName=ZipFileWritten | FileName=/^volta_(log|dox|doxnet)\.zip$/i OR TargetFileName=/volta_(log|dox|doxnet)\.zip$/i | table([@timestamp, ComputerName, UserName, ContextBaseFileName, FileName, TargetFileName, SHA256HashData, aid], limit=200)
3 required fields · View requirements
Required telemetry
- File Creation
Required fields
event.type: Event typeevent.time: Event timetgt.file.path: Written file path
Recommended fields
src.process.name: Writer process
Optional fields
tgt.file.sha256: Written file hash
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'File Creation' | limit 5 | columns event.type, event.time, tgt.file.path
// HUNT: VOLTA staged exfiltration archives written to disk // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1560, T1074.001 // CONF: high | FP: low // FALSE POSITIVES: none expected; the volta_ prefix is specific to this family // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: an archive written whose name is volta_log, volta_dox or volta_doxnet with a zip extension. matches is case-insensitive, which reproduces the CQL /i intent, and the pattern is unanchored at the start like the CQL's path alternative. // REQUIRES: SentinelOne File Creation events // TUNING: None expected. The builder is customer-configured, so a renamed archive will not match; treat a miss as unproven. // LOOKBACK: 30d; set the console time picker or the query window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed archive is not caught. // VALIDATION LEVEL: static-reviewed event.type = 'File Creation' tgt.file.path matches 'volta_(log|dox|doxnet)\\.zip$' | columns event.time, endpoint.name, agent.uuid, src.process.user, src.process.name, tgt.file.path, tgt.file.sha256 | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeActionType: ActionFileName: Written file name
Recommended fields
InitiatingProcessFileName: Writer process
Optional fields
SHA1: Hash. SHA256 is often unpopulated; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | project Timestamp, ActionType, FileName | take 5
// HUNT: VOLTA staged exfiltration archives written to disk // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1560, T1074.001 // CONF: high | FP: low // FALSE POSITIVES: none expected; the volta_ prefix is specific to this family // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a zip written with one of the three staged names. matches regex with a (?i) prefix reproduces the CQL /i intent. // REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents) // TUNING: None expected. A renamed archive will not match. // LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 30d) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed archive is not caught. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceFileEvents | where Timestamp >= ago(30d) | where ActionType == "FileCreated" | where FileName matches regex @"(?i)^volta_(log|dox|doxnet)\.zip$" | project Timestamp, ReportId, DeviceId, DeviceName, RequestAccountName, InitiatingProcessFileName, FileName, FolderPath, SHA1, SHA256 | sort by Timestamp desc | take 200
Looks for: The AI stage POSTs the identity bundle to the OpenRouter chat completions endpoint from the victim machine itself. OpenRouter is a legitimate service, so the signal is the process, not the domain: a native binary that is not a browser or a sanctioned developer tool. FP: developer machines running IDE assistants, scripts, agent frameworks or notebooks that call OpenRouter legitimately. Allowlist sanctioned tools by process name and host group after a 30 day baseline.
Known limitations and deployment notes
- PowerQuery: A browser used as the carrier is excluded by name, so an attacker running inside a browser process is not caught.
- PowerQuery assumes: event.dns.request is the populated DNS field on this tenant; some schema versions use dns.request.
- PowerQuery assumes: src.process.name is the process that issued the lookup.
- KQL – Defender XDR: A browser used as the carrier is excluded by name.
- KQL – Defender XDR assumes: AdditionalFields carries the queried name under DnsQueryString or QueryName on DnsQueryResponse rows.
// HUNT: non-browser process resolving openrouter.ai // MITRE: T1071.001, T1567 // CONF: medium | FP: medium | COST: low | REQUIRES: DnsRequest with process context // SOURCE: Talos 2026-10-31 (OpenRouter chat completions endpoint, third-party service) // FALSE POSITIVES: developer tooling, IDE assistants, agent frameworks, notebooks // TUNING: baseline 30 days, then add sanctioned ContextBaseFileName values (IDE, python, node) per host group // NOTE: openrouter.ai is a LEGITIMATE service. This is a hunt and alert only, never a block. // LOOKBACK: 7d #event_simpleName=DnsRequest | DomainName=/(^|\.)openrouter\.ai$/i | ContextBaseFileName!=/^(chrome|msedge|firefox|brave|opera)\.exe$/i | groupBy([ComputerName, ContextBaseFileName, DomainName], function=[count(as=Requests), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen)]) | sort(Requests, order=desc, limit=200)
4 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.type: Event typeevent.time: Event timeevent.dns.request: Queried namesrc.process.name: Acting process
Fallbacks
event.dns.request→dns.request: Some schema versions populate only the unprefixed field.
Readiness test
event.type = 'DNS Resolved' | limit 5 | columns event.type, event.time, event.dns.request, src.process.name
// HUNT: non-browser process resolving openrouter.ai
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1567
// CONF: medium | FP: medium
// FALSE POSITIVES: developer tooling, IDE assistants, agent frameworks, notebooks
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a DNS lookup of openrouter.ai or a subdomain by a process that is not one of the five browsers, counted per host and process. The domain is matched exactly or as a suffix, like the CQL.
// REQUIRES: SentinelOne DNS Resolved events with the acting process
// TUNING: Baseline 30 days, then add sanctioned process names (IDE, python, node) per host group. openrouter.ai is a legitimate service: hunt and alert only, never block.
// LOOKBACK: 7d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A browser used as the carrier is excluded by name, so an attacker running inside a browser process is not caught.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved'
(event.dns.request in:anycase ('openrouter.ai') or event.dns.request matches '\\.openrouter\\.ai$')
!(src.process.name matches '^(chrome|msedge|firefox|brave|opera)\\.exe$')
| group requests=count(), first_seen=min(event.time), last_seen=max(event.time) by endpoint.name, src.process.name, event.dns.request
| sort -requests
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: Queried nameInitiatingProcessFileName: Acting process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, InitiatingProcessFileName | take 5
// HUNT: non-browser process resolving openrouter.ai
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.001, T1567
// CONF: medium | FP: medium
// FALSE POSITIVES: developer tooling, IDE assistants, agent frameworks, notebooks
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on the endpoint DNS record: openrouter.ai or a subdomain looked up by a process other than the five browsers. There is no endpoint DNS table, so the name is read from AdditionalFields on DnsQueryResponse rows.
// REQUIRES: Defender for Endpoint network telemetry that records DnsQueryResponse in DeviceEvents
// TUNING: Baseline 30 days, then add sanctioned process names per host group. openrouter.ai is a legitimate service: hunt and alert only.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A browser used as the carrier is excluded by name.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(7d)
| where ActionType == "DnsQueryResponse"
| extend Domain = tolower(tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])))
| where Domain == "openrouter.ai" or Domain endswith ".openrouter.ai"
| where not(InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe"))
| summarize Requests = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceId, DeviceName, InitiatingProcessFileName, Domain
| sort by Requests desc
| take 200Looks for: The strongest network-side pairing in the Talos report: the same process values a Roblox inventory through a rolimons.com lookup and also calls OpenRouter for the dossier. Two legitimate services that no ordinary non-browser program touches together.
Known limitations and deployment notes
- PowerQuery: Pid reuse on one host inside the window can merge two processes.
- PowerQuery assumes: src.process.pid identifies one process instance within the window; pid reuse could merge two processes.
- PowerQuery assumes: event.dns.request is the populated DNS field on this tenant.
- KQL – Defender XDR: Process id reuse on one host inside the window can merge two processes.
- KQL – Defender XDR assumes: AdditionalFields carries the queried name under DnsQueryString or QueryName on DnsQueryResponse rows.
- KQL – Defender XDR assumes: InitiatingProcessId identifies one process instance within the window.
// HUNT: single process resolving both openrouter.ai and rolimons.com // MITRE: T1071.001, T1567, T1657 // CONF: high | FP: low | COST: medium | REQUIRES: DnsRequest with process context // SOURCE: Talos 2026-10-31 (Roblox inventory valuation via Rolimons, dossier via OpenRouter) // FALSE POSITIVES: a hobbyist script or bot that uses both services; very rare on managed endpoints // NOTE: both domains are LEGITIMATE third-party services. Detect only, never prevent. // LOOKBACK: 7d #event_simpleName=DnsRequest | DomainName=/(^|\.)(openrouter\.ai|rolimons\.com)$/i | ContextBaseFileName!=/^(chrome|msedge|firefox|brave|opera)\.exe$/i | case { DomainName=/openrouter\.ai$/i | Svc := "openrouter"; DomainName=/rolimons\.com$/i | Svc := "rolimons"; * | Svc := "other"; } | groupBy([aid, ComputerName, ContextProcessId_decimal, ContextBaseFileName], function=[count(Svc, distinct=true, as=Services), collect([DomainName]), min(@timestamp, as=FirstSeen)]) | Services >= 2 | sort(FirstSeen, order=desc, limit=200)
6 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.type: Event typeevent.time: Event timeevent.dns.request: Queried namesrc.process.name: Acting processsrc.process.pid: Acting process idagent.uuid: Host identifier
Fallbacks
event.dns.request→dns.request: Some schema versions populate only the unprefixed field.
Readiness test
event.type = 'DNS Resolved' | limit 5 | columns event.type, event.time, event.dns.request, src.process.name, src.process.pid, agent.uuid
// HUNT: single process resolving both openrouter.ai and rolimons.com
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1567, T1657
// CONF: high | FP: low
// FALSE POSITIVES: a hobbyist script or bot that uses both services; very rare on managed endpoints
// EQUIVALENCE: equivalent-with-schema-assumptions - Same logic: one process that looked up both openrouter.ai and rolimons.com, browsers excluded. The CQL's distinct-service count becomes one conditional count per service, both required above zero.
// REQUIRES: SentinelOne DNS Resolved events with the acting process and its pid
// TUNING: A hobbyist script that uses both services is the only expected match. Both domains are legitimate: detect only, never block.
// LOOKBACK: 7d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Pid reuse on one host inside the window can merge two processes.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved'
(event.dns.request in:anycase ('openrouter.ai', 'rolimons.com') or event.dns.request matches '\\.(openrouter\\.ai|rolimons\\.com)$')
!(src.process.name matches '^(chrome|msedge|firefox|brave|opera)\\.exe$')
| group openrouter_lookups=count(event.dns.request contains 'openrouter.ai'), rolimons_lookups=count(event.dns.request contains 'rolimons.com'), first_seen=min(event.time) by agent.uuid, endpoint.name, src.process.pid, src.process.name
| filter openrouter_lookups > 0 and rolimons_lookups > 0
| sort -first_seen
| limit 200Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: Queried nameInitiatingProcessFileName: Acting processInitiatingProcessId: Acting process id
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, InitiatingProcessFileName, InitiatingProcessId | take 5
// HUNT: single process resolving both openrouter.ai and rolimons.com
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.001, T1567, T1657
// CONF: high | FP: low
// FALSE POSITIVES: a hobbyist script or bot that uses both services; very rare on managed endpoints
// EQUIVALENCE: equivalent-with-schema-assumptions - Same logic on the endpoint DNS record: one process instance that looked up both domains, browsers excluded. The name is read from AdditionalFields on DnsQueryResponse rows.
// REQUIRES: Defender for Endpoint network telemetry that records DnsQueryResponse in DeviceEvents
// TUNING: A hobbyist script that uses both services is the only expected match. Detect only, never block.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Process id reuse on one host inside the window can merge two processes.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(7d)
| where ActionType == "DnsQueryResponse"
| extend Domain = tolower(tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])))
| where Domain == "openrouter.ai" or Domain endswith ".openrouter.ai" or Domain == "rolimons.com" or Domain endswith ".rolimons.com"
| where not(InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe"))
| summarize OpenRouterLookups = countif(Domain == "openrouter.ai" or Domain endswith ".openrouter.ai"), RolimonsLookups = countif(Domain == "rolimons.com" or Domain endswith ".rolimons.com"), FirstSeen = min(Timestamp) by DeviceId, DeviceName, InitiatingProcessId, InitiatingProcessFileName
| where OpenRouterLookups > 0 and RolimonsLookups > 0
| sort by FirstSeen desc
| take 200Looks for: Talos ties VOLTA token theft to bypassing Chrome App-Bound Encryption and recommends alerting when Chrome is launched with --headless from any process not in a known developer set. This hunts the root browser process only, excluding the browser spawning its own children. FP: test automation, PDF and screenshot generation, web scraping jobs and CI agents on developer or build hosts. Exclude sanctioned parents for those host groups.
Known limitations and deployment notes
- PowerQuery: Selenium, Playwright, report-to-PDF and CI jobs match by design and need an allowlist.
- PowerQuery assumes: On a Process Creation event src.process.parent.name is the creator's own parent, which stands in for the CQL's grandparent.
- KQL – Defender XDR: Selenium, Playwright, report-to-PDF and CI jobs match by design and need an allowlist.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full launch arguments of the created process.
// HUNT: Chrome or Edge launched with --headless by a non-browser parent // MITRE: T1555.003, T1539 // CONF: medium | FP: medium | COST: low | REQUIRES: ProcessRollup2 // SOURCE: Talos 2026-10-31 countermeasures (single source for the headless angle) // FALSE POSITIVES: Selenium or Playwright test runs, report-to-PDF jobs, CI agents // TUNING: add sanctioned developer parents (for example your CI agent or IDE) to the ParentBaseFileName exclusion, or scope by host group // LOOKBACK: 7d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(chrome|msedge)\.exe$/i | CommandLine=/--headless/i | CommandLine!=/--type=/i | ParentBaseFileName!=/^(chrome|msedge)\.exe$/i | table([@timestamp, ComputerName, UserName, GrandparentBaseFileName, ParentBaseFileName, FileName, CommandLine, SHA256HashData, aid], limit=200)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timetgt.process.name: Created process nametgt.process.cmdline: Created command linesrc.process.name: Creator process
Recommended fields
src.process.parent.name: Creator's parent
Optional fields
tgt.process.image.sha256: Hash
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' | limit 5 | columns event.type, event.time, tgt.process.name, tgt.process.cmdline, src.process.name
// HUNT: Chrome or Edge launched with --headless by a non-browser parent
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1555.003, T1539
// CONF: medium | FP: medium
// FALSE POSITIVES: Selenium or Playwright test runs, report-to-PDF jobs, CI agents
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a process start: chrome or msedge with --headless, not a --type= child, and not started by a browser. The created process is tgt.process.* and its creator is src.process.*. contains is case-insensitive, which reproduces the CQL /i intent.
// REQUIRES: SentinelOne Process Creation events with command line
// TUNING: Add sanctioned developer parents (a CI agent, an IDE) to the creator exclusion, or scope by host group.
// LOOKBACK: 7d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Selenium, Playwright, report-to-PDF and CI jobs match by design and need an allowlist.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name in:anycase ('chrome.exe', 'msedge.exe')
tgt.process.cmdline contains '--headless'
!(tgt.process.cmdline contains '--type=')
!(src.process.name in:anycase ('chrome.exe', 'msedge.exe'))
| columns event.time, endpoint.name, agent.uuid, src.process.user, src.process.parent.name, src.process.name, tgt.process.name, tgt.process.cmdline, tgt.process.image.sha256
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command lineInitiatingProcessFileName: Creator process
Recommended fields
InitiatingProcessParentFileName: Grandparent
Optional fields
SHA1: Hash. SHA256 is often unpopulated; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: Chrome or Edge launched with --headless by a non-browser parent
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1555.003, T1539
// CONF: medium | FP: medium
// FALSE POSITIVES: Selenium or Playwright test runs, report-to-PDF jobs, CI agents
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: chrome or msedge created with --headless, not a --type= child, and not started by a browser. The creator is InitiatingProcessFileName and the grandparent is InitiatingProcessParentFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Add sanctioned developer parents to the creator exclusion, or scope by host group.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Selenium, Playwright, report-to-PDF and CI jobs match by design and need an allowlist.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where FileName in~ ("chrome.exe", "msedge.exe")
| where ProcessCommandLine contains "--headless"
| where not(ProcessCommandLine contains "--type=")
| where not(InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe"))
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessParentFileName, InitiatingProcessFileName, FileName, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: Talos says the customer supplies a Telegram channel and receives the dossier in a Telegram inbox, but does not publish the Telegram hostname or API path the implant calls. This hunt is therefore an inference from the report, not a sourced indicator, and nothing here is shipped as an IOC. FP: monitoring bots, alerting integrations, chat clients and scripts that post to Telegram. Baseline first and review only processes new to the host group.
Known limitations and deployment notes
- PowerQuery: The destination is inferred, so a miss proves nothing about the family.
- PowerQuery: Alerting bots, scripts and admin automation match by design.
- PowerQuery assumes: event.dns.request is the populated DNS field on this tenant; some schema versions use dns.request.
- PowerQuery assumes: api.telegram.org is the public Bot API host used as a heuristic; the source names a Telegram channel but no hostname.
- KQL – Defender XDR: The destination is inferred, so a miss proves nothing about the family.
- KQL – Defender XDR assumes: AdditionalFields carries the queried name under DnsQueryString or QueryName on DnsQueryResponse rows.
// HUNT: non-browser, non-Telegram-client process resolving api.telegram.org // MITRE: T1567, T1041 // CONF: low | FP: medium | COST: low | REQUIRES: DnsRequest with process context // NOTE: INFERRED. Talos names a Telegram channel as the destination but publishes no hostname. api.telegram.org is the // public Bot API host, used here as a hunt heuristic only. It is not an IOC from any saved source. // FALSE POSITIVES: alerting bots, scripts, chat clients, admin automation // TUNING: baseline 30 days, allowlist recurring ContextBaseFileName values per host group, review only new processes // LOOKBACK: 7d #event_simpleName=DnsRequest | DomainName=/^api\.telegram\.org$/i | ContextBaseFileName!=/^(telegram|chrome|msedge|firefox|brave|opera)\.exe$/i | groupBy([ComputerName, ContextBaseFileName], function=[count(as=Requests), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen)]) | sort(Requests, order=desc, limit=200)
4 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.type: Event typeevent.time: Event timeevent.dns.request: Queried namesrc.process.name: Acting process
Fallbacks
event.dns.request→dns.request: Some schema versions populate only the unprefixed field.
Readiness test
event.type = 'DNS Resolved' | limit 5 | columns event.type, event.time, event.dns.request, src.process.name
// HUNT: non-browser, non-Telegram-client process resolving api.telegram.org
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1567, T1041
// CONF: low | FP: medium
// FALSE POSITIVES: alerting bots, scripts, chat clients, admin automation
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a DNS lookup of api.telegram.org by a process that is not Telegram or one of the five browsers, counted per host and process. The host is inferred as the Bot API endpoint, not a published indicator.
// REQUIRES: SentinelOne DNS Resolved events with the acting process
// TUNING: Baseline 30 days, allowlist recurring process names per host group, and review only new processes.
// LOOKBACK: 7d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The destination is inferred, so a miss proves nothing about the family. Alerting bots, scripts and admin automation match by design.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved'
event.dns.request in:anycase ('api.telegram.org')
!(src.process.name matches '^(telegram|chrome|msedge|firefox|brave|opera)\\.exe$')
| group requests=count(), first_seen=min(event.time), last_seen=max(event.time) by endpoint.name, src.process.name
| sort -requests
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: Queried nameInitiatingProcessFileName: Acting process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, InitiatingProcessFileName | take 5
// HUNT: non-browser, non-Telegram-client process resolving api.telegram.org
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1567, T1041
// CONF: low | FP: medium
// FALSE POSITIVES: alerting bots, scripts, chat clients, admin automation
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on the endpoint DNS record: api.telegram.org looked up by a process other than Telegram or the five browsers. The name is read from AdditionalFields on DnsQueryResponse rows. The host is an inferred heuristic, not a published indicator.
// REQUIRES: Defender for Endpoint network telemetry that records DnsQueryResponse in DeviceEvents
// TUNING: Baseline 30 days, allowlist recurring process names per host group, and review only new processes.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The destination is inferred, so a miss proves nothing about the family.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(7d)
| where ActionType == "DnsQueryResponse"
| extend Domain = tolower(tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])))
| where Domain == "api.telegram.org"
| where not(InitiatingProcessFileName in~ ("telegram.exe", "chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe"))
| summarize Requests = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceId, DeviceName, InitiatingProcessFileName
| sort by Requests desc
| take 200Looks for: Both build names Talos published are 12 characters of mixed-case letters and digits. This is a heuristic derived from two samples of one build, not a documented property of the builder, so it ranks hosts for review rather than alerting. FP: some installers, updaters and portable tools use generated names from Downloads, Desktop or AppData. Prefer rarity: review names seen on only one or two hosts.
Known limitations and deployment notes
- PowerQuery: Installers and updaters that generate random temporary names match by design.
- PowerQuery: A build with a different name length is not caught.
- PowerQuery assumes: tgt.process.image.path holds the full image path with backslash separators on Windows.
- PowerQuery assumes: The pattern is a heuristic from two sample filenames, not a documented builder behaviour.
- KQL – Defender XDR: Installers and updaters that generate random temporary names match by design.
- KQL – Defender XDR: The group key uses SHA1 because SHA256 is often unpopulated, so the SHA256 the CQL groups on is not shown.
- KQL – Defender XDR assumes: FolderPath holds the full image path including the file name.
- KQL – Defender XDR assumes: The pattern is a heuristic from two sample filenames, not a documented builder behaviour.
// HUNT: 12 character mixed-case alphanumeric executable launched from a user-writable path // MITRE: T1036.005, T1204.002 // CONF: low | FP: medium | COST: medium | REQUIRES: ProcessRollup2 // NOTE: HEURISTIC derived from the two filenames in the Talos sample table. Not a documented builder behavior. // FALSE POSITIVES: installers and updaters that generate random temporary names // TUNING: sort by Hosts ascending and review names seen on one or two hosts; add known installer paths to an exclusion // LOOKBACK: 14d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^[A-Za-z0-9]{12}\.exe$/ | FileName=/[0-9]/ | FileName=/[A-Z]/ | FileName=/[a-z]/ | ImageFileName=/\\(Users\\[^\\]+\\(AppData|Downloads|Desktop)|ProgramData|Windows\\Temp)\\/i | groupBy([FileName, ImageFileName, SHA256HashData], function=[count(aid, distinct=true, as=Hosts), min(@timestamp, as=FirstSeen), collect([ComputerName])]) | sort(Hosts, order=asc, limit=200)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timetgt.process.name: Created process nametgt.process.image.path: Created process pathagent.uuid: Host identifier
Recommended fields
endpoint.name: Hostname
Optional fields
tgt.process.image.sha256: Hash
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' | limit 5 | columns event.type, event.time, tgt.process.name, tgt.process.image.path, agent.uuid
// HUNT: 12 character mixed-case alphanumeric executable launched from a user-writable path
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1036.005, T1204.002
// CONF: low | FP: medium
// FALSE POSITIVES: installers and updaters that generate random temporary names
// EQUIVALENCE: equivalent-with-schema-assumptions - Same heuristic on a process start: a 12 character name with a digit, an upper-case and a lower-case letter, running from a user-writable path, counted by distinct hosts. The name checks use matches:matchcase to keep the CQL's case-sensitive intent; the path check is case-insensitive like the CQL /i.
// REQUIRES: SentinelOne Process Creation events with the image path
// TUNING: Sort by hosts ascending and review names seen on one or two hosts; add known installer paths to an exclusion.
// LOOKBACK: 14d; set the console time picker or the query window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Installers and updaters that generate random temporary names match by design. A build with a different name length is not caught.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name matches:matchcase '^[A-Za-z0-9]{12}\\.exe$'
tgt.process.name matches:matchcase '[0-9]'
tgt.process.name matches:matchcase '[A-Z]'
tgt.process.name matches:matchcase '[a-z]'
tgt.process.image.path matches '\\\\(Users\\\\[^\\\\]+\\\\(AppData|Downloads|Desktop)|ProgramData|Windows\\\\Temp)\\\\'
| group hosts=estimate_distinct(agent.uuid), first_seen=min(event.time), host_sample=any(endpoint.name) by tgt.process.name, tgt.process.image.path, tgt.process.image.sha256
| sort +hosts
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process pathDeviceId: Host identifier
Recommended fields
DeviceName: Hostname
Optional fields
SHA1: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, FolderPath, DeviceId | take 5
// HUNT: 12 character mixed-case alphanumeric executable launched from a user-writable path
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1204.002
// CONF: low | FP: medium
// FALSE POSITIVES: installers and updaters that generate random temporary names
// EQUIVALENCE: equivalent-with-schema-assumptions - Same heuristic: a 12 character name with a digit, an upper-case and a lower-case letter, running from a user-writable path, counted by distinct hosts. The name checks are case-sensitive regexes and the path check carries a (?i) prefix, matching the CQL.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Sort by Hosts ascending and review names seen on one or two hosts; add known installer paths to an exclusion.
// LOOKBACK: 14d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Installers and updaters that generate random temporary names match by design. The group key uses SHA1 because SHA256 is often unpopulated, so the SHA256 the CQL groups on is not shown.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(14d)
| where FileName matches regex @"^[A-Za-z0-9]{12}\.exe$"
| where FileName matches regex @"[0-9]"
| where FileName matches regex @"[A-Z]"
| where FileName matches regex @"[a-z]"
| where FolderPath matches regex @"(?i)\\(Users\\[^\\]+\\(AppData|Downloads|Desktop)|ProgramData|Windows\\Temp)\\[^\\]*$"
| summarize Hosts = dcount(DeviceId), FirstSeen = min(Timestamp), HostSample = any(DeviceName) by FileName, FolderPath, SHA1
| sort by Hosts asc
| take 200Detection Rules by Platform
CrowdStrike: Custom IOA
| IOA name | Pattern | Exclusions | Deployment | Promotes |
|---|---|---|---|---|
| VOLTA headless browser launch | Process Creation: image chrome.exe or msedge.exe, command line contains --headless and not --type= | Sanctioned automation and CI parents per host group | Detect only. Single-source behavior and a legitimate feature; no prevent. | Promote Q5 |
| VOLTA exfil archive written | File Creation: file name matches volta_(log|dox|doxnet).zip | None expected | Detect, high severity. Prevent only after a second source confirms the naming. | Promote Q2 |
| LLM API from non-browser process | Domain Name rule for openrouter.ai where image is not a browser | Sanctioned developer tools and approved AI integrations | Detect only, low severity. Legitimate service; never prevent. | Promote Q3 |
No IOA in this pack is set to prevent. Everything here is either single-sourced or points at a legitimate service. Revisit after a second vendor publishes on VOLTA.
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| VOLTA headless browser launch | Q5, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| VOLTA exfil archive written | Q2, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| LLM API from non-browser process | Q3, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
Create the rule with POST /web/api/v2.1/cloud-detection/rules, queryType: "scheduled" and queryLang: "2.0", with the query in data.scheduledParams.query. Use 2.0 operator spellings: a rule written with the 1.0 token ContainsCIS was accepted and never fired on a tenant. The API does not warn, so lint the body before deploying.
Microsoft Defender: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| VOLTA headless browser launch | Q5, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself |
| VOLTA exfil archive written | Q2, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself |
| LLM API from non-browser process | Q3, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | Make the final result include Timestamp, ReportId and DeviceId: Microsoft recommends them for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself |
Q1, Q4, Q6 and Q7 stay a hunt in this pack, not a rule. A rule can generate only 150 alerts per run. Continuous (NRT) frequency needs a single table and no comment lines, so delete the generated comment header from the query first.
Machine-Readable IOC Appendix
Grouped IOC Quick-Copy
One-click blocks. There is no attacker infrastructure, so the Falcon CSV is deliberately short and every row is detect. Host artifacts and behaviors are the durable detection.
type,value,action,severity,expiration,description,tags sha256,57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279,detect,high,2027-05-01,VOLTA sample per Talos (single source; builder output differs per customer),campaign:VOLTA domain,openrouter.ai,detect,low,2027-02-01,LEGITIMATE service used by VOLTA AI stage; alert only on non-browser or unsanctioned process; never prevent,campaign:VOLTA domain,rolimons.com,detect,low,2027-02-01,LEGITIMATE service used by VOLTA for Roblox valuation; never prevent,campaign:VOLTA
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert FileSha256,57ef4242666d78c50df145b34023df564f0fad38812d6a580e66433d427e2279,Audit,VOLTA sample per Talos,VOLTA sample per Talos (single source; builder output differs per customer),2027-05-01T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,openrouter.ai,Audit,LEGITIMATE service used by VOLTA AI stage; alert only on non,LEGITIMATE service used by VOLTA AI stage; alert only on non-browser or unsanctioned process; never prevent,2027-02-01T00:00:00.0Z,Low,Investigate the device and pivot into the pack's queries,,,,True DomainName,rolimons.com,Audit,LEGITIMATE service used by VOLTA for Roblox valuation; never,LEGITIMATE service used by VOLTA for Roblox valuation; never prevent,2027-02-01T00:00:00.0Z,Low,Investigate the device and pivot into the pack's queries,,,,True
Column names and allowed values are from Microsoft's documented parameter table. Check each expirationTime before importing: an indicator whose date has passed is already expired. Download the sample CSV from the Import page to confirm the column order before a bulk import. Each file takes at most 500 indicators. Learn describes the import per entity type, so if a mixed file is rejected, split it by indicatorType. An imported indicator does nothing unless the matching Advanced features are on (for example Custom network indicators and Allow or block file).
This pack does not ship a SentinelOne import block: the import format could not be verified against SentinelOne's own documentation. Export a sample from your console and the block can be added with confidence.
# Host artifacts reported by Talos (names only, not Falcon IOC types) %APPDATA%\volta_debug.txt Identity_Report.txt AI_Analysis.txt volta_log.zip volta_dox.zip volta_doxnet.zip # Build executable names (random per build) 9BY0tjwOc3ut.exe yLP9m5J3i2Aw.exe
Non-browser process resolving openrouter.ai, especially together with rolimons.com (same process) Bare "Mozilla/5.0" User-Agent POSTing JSON to /api/v1/chat/completions on openrouter.ai Request body naming anthropic/claude-opus-4.6, moonshotai/kimi-k2 or google/gemini-2.5-flash (needs TLS inspection) chrome.exe or msedge.exe with --headless launched by a parent that is not a browser or sanctioned automation volta_log.zip / volta_dox.zip / volta_doxnet.zip written under a user profile Self-deleting executable: process image missing from disk shortly after first run Possible (inferred, unconfirmed): non-browser process resolving api.telegram.org
# Treat any confirmed VOLTA host as a full identity compromise. Order matters. # 0) Preserve %APPDATA%\volta_debug.txt and a memory image BEFORE reimaging (it shows what was taken). # 1) Revoke tokens first: Microsoft/Entra sessions (playbook P3), Google, Discord, Telegram, Steam, Roblox sessions. # 2) Reset passwords for every account saved in a browser or mail client on the host, from a clean device. # 3) Rotate SSH keys, cloud-provider keys (gcloud and others), and VPN client configs (OpenVPN, Hide.me). # 4) Crypto: if a seed phrase was ever in plaintext on disk, move funds to a NEW wallet whose seed # was generated on an air-gapped device. # 5) Review mailbox rules, new OAuth consents and recent receipt-sender searches for the user. # 6) Reimage the host after evidence is preserved.
# Audit-only checks. Read-only. Run from an elevated PowerShell on a managed endpoint. # 1) Chrome App-Bound Encryption policy must not be disabled (value 0) Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Google\Chrome' -Name ApplicationBoundEncryptionEnabled -ErrorAction SilentlyContinue # 2) ASR rule: block executables unless prevalence/age/trusted-list criterion is met (GUID per Microsoft reference) (Get-MpPreference).AttackSurfaceReductionRules_Ids (Get-MpPreference).AttackSurfaceReductionRules_Actions # 3) Entra: list users with recent risky sign-ins for review after an endpoint hit (tenant-specific)
Detection Validation Gates
| Gate | Check |
|---|---|
| Telemetry ready | Confirm process creation with command line and hash (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents), archive and executable writes (CrowdStrike: ZipFileWritten, PeFileWritten, NewExecutableWritten) and DNS lookup with requesting process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents DNS action type) are present fleet-wide. Confirm the DNS event carries the process name in your tenant before trusting Q3, Q4 and Q6. |
| Benign baseline | Run Q3, Q5, Q6 and Q7 over 30 days. Allowlist sanctioned developer tools, CI agents and installers by process name and host group before any alerting. Q1, Q2 and Q4 should return zero. |
| Positive tests | Do not run malware. Create a benign file named volta_dox.zip in a test profile to exercise Q2. Launch a headless Chrome from a test script to exercise Q5. Resolve openrouter.ai and rolimons.com from one test process to exercise Q4. |
| Promotion | IOAs ship detect only (section 9). Promote to prevent only for the archive-name IOA and only after a second independent source confirms the naming. Never prevent on openrouter.ai or rolimons.com. |
Hardening, Tiered & Deployable
VOLTA is delivered malware with no CVE, so there is no patch. Hardening targets what it relies on (browser secrets, long-lived sessions, execution from user-writable paths) and shrinks the value of what it steals. Controls are anchored to MITRE mitigations from the saved ATT&CK pages plus vendor documentation.
- Keep Chrome App-Bound Encryption on. Confirm
ApplicationBoundEncryptionEnabledis not 0 (Google, Chrome 127 policy). Talos says VOLTA works to bypass ABE; do not hand it a free path. M1051 (T1555.003), M1054 (T1539). Verify with playbook P1. - Alert on headless browser launches from non-browser parents (Q5 / IOA). Talos names controlling
--headlessas the way to block the ABE decryption path. Argument-level launch control needs an EDR rule; native application control does not match on command-line arguments. flag: best-practice, no formal benchmark - Pre-stage token revocation. Have the Entra
Revoke-MgUserSignInSessionprocedure ready (P3). M1047 audit, M1032 multi-factor. - Preserve evidence. Make capturing
%APPDATA%\volta_debug.txtpart of the endpoint triage checklist (P4), since the executable deletes itself.
- ASR audit then block for unproven executables. Microsoft ASR rule "Block executable files from running unless they meet a prevalence, age, or trusted list criterion" (P2). Starts in audit; randomly named per-customer builds are exactly the unproven-prevalence case. Microsoft ASR reference.
- Shorten web and OAuth session lifetimes and require phishing-resistant MFA so stolen cookies and refresh tokens age out. M1032 (T1539), M1018 (T1555.003).
- Restrict unsanctioned LLM API egress at the proxy for server and kiosk segments with no AI use, while keeping the Falcon IOC at detect. Note this removes only the AI step: Talos says VOLTA still runs without the LLM stage, so the theft and exfil continue. flag: best-practice, no formal benchmark
- User training on session and credential reuse for staff who use wallets, gaming and personal accounts on work devices. M1017.
- Move secrets out of browsers into a managed password manager or SSO with hardware-backed keys; Talos recommends hardware-backed credential storage. M1027 (T1555.003).
- Device-bound sessions and conditional access (token protection, compliant-device requirement) so a stolen token fails off the original machine. M1032, M1021.
- Separate crypto, gaming and personal accounts from corporate endpoints, and keep seed phrases off disk.
- Default-deny application control for user-writable paths in managed fleets. flag: best-practice, no formal benchmark in the saved sources.
Deployable Playbooks
Every step lists Prerequisites, Reboot required and Rollback. Replace placeholders such as the user principal name and evidence share before running.
P1 Verify (and restore) Chrome App-Bound Encryption policy
Prerequisites: local admin or an MDM/GPO that manages Chrome policy; Chrome 127 or later (per Google).
Reboot required: no (restart Chrome to apply).
Rollback: re-create the previous value recorded in step 1 (for example: Set-ItemProperty ... -Value 0), or delete the value to return to the browser default.
# 1) Record the current state (read-only)
$k = 'HKLM:\SOFTWARE\Policies\Google\Chrome'
Get-ItemProperty $k -Name ApplicationBoundEncryptionEnabled -ErrorAction SilentlyContinue |
Select-Object ApplicationBoundEncryptionEnabled
# 2) If the value exists and is 0, remove it so ABE returns to the default (enabled)
if ((Get-ItemProperty $k -Name ApplicationBoundEncryptionEnabled -ErrorAction SilentlyContinue).ApplicationBoundEncryptionEnabled -eq 0) {
Remove-ItemProperty $k -Name ApplicationBoundEncryptionEnabled
}
# Roaming-profile estates: Google documents this policy for that case; confirm before removing.
P2 ASR rule for unproven executables: audit first
Prerequisites: Microsoft Defender Antivirus active; local admin; pilot ring; review audit events for 2 to 4 weeks. Reboot required: no. Rollback: Remove-MpPreference -AttackSurfaceReductionRules_Ids 01443614-cd74-433a-b99e-2ecdc07bfc25 # 1) Audit mode (log only) Add-MpPreference -AttackSurfaceReductionRules_Ids 01443614-cd74-433a-b99e-2ecdc07bfc25 ` -AttackSurfaceReductionRules_Actions AuditMode # 2) Review audit hits (Defender event log) and add legitimate tools to your exclusions / trusted list. # 3) Only then, move a ring to block: # Set-MpPreference -AttackSurfaceReductionRules_Ids 01443614-cd74-433a-b99e-2ecdc07bfc25 ` # -AttackSurfaceReductionRules_Actions Enabled
P3 Revoke Microsoft Entra sessions for an affected user
Prerequisites: Microsoft Graph PowerShell with User.ReadWrite.All (or equivalent); approval to sign the user out everywhere. Reboot required: no. Rollback: none required. The user signs in again; the revocation itself cannot be undone and that is the point. Pair with a password reset from a clean device. Connect-MgGraph -Scopes 'User.ReadWrite.All' Revoke-MgUserSignInSession -UserId 'jdoe@internal-host.example.com' # Repeat for each affected user. Follow with password reset and MFA method review.
P4 Read-only triage and evidence preservation on a suspect host
Prerequisites: elevated PowerShell; an evidence share you control (EVIDENCE-SHARE below is a placeholder).
Reboot required: no. Do not reboot or reimage until the copy completes.
Rollback: none required (read and copy only; nothing on the host is modified).
$names = 'volta_debug.txt','Identity_Report.txt','AI_Analysis.txt','volta_log.zip','volta_dox.zip','volta_doxnet.zip'
Get-ChildItem -Path C:\Users -Recurse -Force -ErrorAction SilentlyContinue -Include $names |
Select-Object FullName, Length, CreationTime, LastWriteTime
# Preserve the harvest log (records what was collected and whether the LLM call succeeded):
Get-ChildItem -Path C:\Users -Recurse -Force -ErrorAction SilentlyContinue -Filter volta_debug.txt |
ForEach-Object { Copy-Item $_.FullName -Destination '\\EVIDENCE-SHARE\volta\' }
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the host in your EDR. Do not power off. Block nothing at the domain level for openrouter.ai or rolimons.com. | SOC L2 | Containment timestamp; Q1 to Q4 rows |
| Isolate: by platform | CrowdStrike: network-contain the host. SentinelOne: network quarantine (Disconnect from Network; confirm the label in your console version). Microsoft Defender: Isolate device (full network isolation). | SOC L2 | Containment timestamp; Q1 to Q4 rows |
| Preserve | Copy %APPDATA%\volta_debug.txt and any volta_*.zip; capture memory if policy allows (P4). The executable may already be gone. | IR | Hashes of copied evidence |
| Revoke | Revoke Entra sessions (P3) and sessions for Google, Discord, Telegram, Steam and Roblox; reset passwords from a clean device; rotate SSH, cloud and VPN keys. | IR + identity team | Revocation log per account |
| Eradicate | Reimage the host after evidence is preserved. Remove any randomly named executable located by Q1 and Q7. | IR | Reimage record |
| Recover | Wallets: migrate funds to a new wallet with a seed generated on an air-gapped device. Review mailbox rules and OAuth consents for the user. | IR + user | Wallet migration confirmation; consent review |
| Hunt | Run Q4, Q3 and Q2 fleet-wide for the 30 days before the hit; search proxy logs for the OpenRouter pattern (N3). | Threat hunt | Fleet sweep results |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1204.002 | Published sample / build names | Q1 | none | Partial one build only | Partial: same limit as CrowdStrike | Partial: Q1 telemetry gap |
| T1560 | Exfil archives written | Q2 | IOA 2 | Good name may be changed by customer | Good, with assumptions | Good, with assumptions |
| T1071.001 | LLM API call from non-browser process | Q3, Q4 | IOA 3 | Good for the AI stage; absent if no key configured | Good, with assumptions | Good, with assumptions |
| T1555.003 / T1539 | Headless Chrome ABE bypass path | Q5 | IOA 1 | Partial other bypasses not covered | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1567 | Telegram exfil (inferred) | Q6 | none | Partial unconfirmed host | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1036.005 | Random 12 character names | Q7 | none | Partial heuristic | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1555 / T1110.002 | Wi-Fi API dump, wallet cracking | none | none | GAP in-process, no endpoint event | GAP | GAP |
| T1113 | Screenshots | none | none | GAP no endpoint event | GAP | GAP |
| T1552 / T1005 | Bulk file reads of keys, wallets, browser stores | none | none | GAP no generic file-read event; compensate with hardening | GAP | GAP |
| T1070.004 | Self-deletion | none | none | GAP no verified delete event used; rely on N1, N2 | GAP | GAP |
| T1114.002 / T1550.001 | SaaS session reuse | none | none | GAP outside endpoint telemetry; N4 | GAP | GAP |
| Initial access | Delivery vector | none | none | GAP not described by Talos | GAP | GAP |
Validation gates: see section 11. Coverage is intentionally conservative: the biggest gaps (bulk file reads, in-process API calls, SaaS reuse and delivery) are outside what endpoint telemetry can see, so hardening and token revocation carry that load.
Hunt Summary Ticket
TITLE: Hunt - VOLTA / VOLTA-AUTODOXER infostealer (LLM victim profiling via OpenRouter)
SEVERITY: High (credential, session, wallet and key theft; self-deleting)
SCOPE: Windows endpoints; identity and SaaS accounts of affected users
HYPOTHESIS: A per-customer VOLTA build ran on a host, harvested secrets, called OpenRouter for a
victim dossier, wrote volta_*.zip archives, exfiltrated them and deleted itself.
No attacker-owned infrastructure: hunt host artifacts and process-to-service traffic.
QUERIES RUN: Q1 sample hash/names | Q2 exfil archives | Q3 non-browser to openrouter.ai |
Q4 openrouter.ai + rolimons.com same process | Q5 headless browser | Q6 Telegram (inferred) |
Q7 random-name exe heuristic + Native N1-N5
DO FIRST: Q4, Q2, Q1. Any hit: preserve volta_debug.txt, revoke tokens, rotate credentials, then reimage.
FINDINGS: <pending analyst execution>
GAPS: Initial access unknown; bulk file reads, in-process API calls and screenshots have no
endpoint event; SaaS token reuse is outside endpoint telemetry (N4); self-delete not covered.
ACTIONS: Keep Chrome ABE on (P1); ASR audit (P2); token revocation ready (P3); never prevent on
openrouter.ai or rolimons.com; promote IOAs at detect only.
OWNER: HuntPack
VERSION: v0.1 - 2026-11-01
Changelog
References
| Tier | Source | Used for | Accessed |
|---|---|---|---|
| 1 | Cisco Talos: Appraisal by AI, VOLTA infostealer | All threat facts, sample details, countermeasures | 2026-11-01 |
| 1 | Google Security Blog: Improving the security of Chrome cookies on Windows | App-Bound Encryption and policy name | 2026-11-01 |
| 2 | MITRE ATT&CK T1555.003 | Technique and mitigations | 2026-11-01 |
| 2 | MITRE ATT&CK T1539 | Technique and mitigations | 2026-11-01 |
| 1 | Microsoft Learn: ASR rules reference | ASR rule GUID and behavior | 2026-11-01 |
| 1 | Microsoft Learn: Revoke-MgUserSignInSession | Session revocation | 2026-11-01 |
HuntPack v0.1 · VOLTA / VOLTA-AUTODOXER Infostealer · Generated 2026-11-01 · Defensive use only, no malware code. Single primary source: validate field names in your tenant and confirm the DNS event carries the process name before promoting any query to alerting.