Behavior-based detection engineering
Rare Blockchain RPC Access Followed by a New Destination
Detects first-seen blockchain RPC activity from scripting or runtime processes when the same process quickly reaches a separate external destination, a pattern consistent with dead-drop C2 resolution.
Behavior
What it detects
A scripting or runtime process on an endpoint with no recent blockchain-RPC history contacts a public RPC service and the same process reaches a different external destination within a short window, consistent with a dead-drop resolver returning the next-stage location.
Engineering decision
Why this detection
EtherHiding is difficult to operationalize as a simple IOC rule because the blockchain RPC provider is normally legitimate and the contract output can rotate.
This Detection deliberately targets a narrower, higher-confidence endpoint pattern: a scripting or runtime process on a device without recent RPC history contacts a public blockchain RPC service and the same stable process quickly reaches a different destination.
Browser-only EtherHiding is kept in the Hunt rather than forced into the primary analytic, because a browser can legitimately interact with Web3 services and generate much noisier follow-on traffic.
Signal chain
Detection logic
- Define the organization's public blockchain RPC provider category separately from malicious IOC lists.
- Baseline device-level RPC usage over thirty days.
- Limit the primary candidate set to scripting, runtime, and native execution processes with stronger malware relevance.
- Require the same stable process identity to contact a non-RPC destination within five minutes.
- Preserve the RPC destination, follow-on destination, process, command line, user, and device for triage.
- Confirm approved Web3 development, wallets, monitoring, and automation before escalating.
Primary analytic
Query
Q-01Detection logicRare blockchain RPC access followed by a new destination
What this checks
Generate a candidate when a scripting/runtime process on a device with no recent blockchain-RPC history contacts a public RPC service and the same process reaches a different external destination within five minutes.
KQL
let current_window = 1d;
let baseline_window = 30d;
let runtime_processes = dynamic(['python.exe', 'pythonw.exe', 'node.exe', 'powershell.exe', 'pwsh.exe', 'mshta.exe', 'wscript.exe', 'cscript.exe', 'rundll32.exe', 'curl.exe']);
let recent_rpc =
DeviceNetworkEvents
| where Timestamp >= ago(current_window)
| where isnotempty(RemoteUrl)
| where InitiatingProcessFileName in~ (runtime_processes)
| where isnotempty(InitiatingProcessUniqueId)
| where (
RemoteUrl endswith "nodies.app"
or RemoteUrl endswith "tenderly.co"
or RemoteUrl endswith "1rpc.io"
or RemoteUrl endswith "drpc.org"
or RemoteUrl endswith "publicnode.com"
or RemoteUrl endswith "ankr.com"
or RemoteUrl endswith "quiknode.pro"
or RemoteUrl endswith "blastapi.io"
)
| project
RpcTime=Timestamp,
DeviceId,
DeviceName,
AccountUpn=InitiatingProcessAccountUpn,
ProcessName=InitiatingProcessFileName,
ProcessCommandLine=InitiatingProcessCommandLine,
ProcessUniqueId=InitiatingProcessUniqueId,
RpcUrl=tolower(RemoteUrl),
RpcIP=RemoteIP,
RpcPort=RemotePort;
let prior_rpc =
DeviceNetworkEvents
| where Timestamp between (ago(baseline_window) .. ago(current_window))
| where isnotempty(RemoteUrl)
| where (
RemoteUrl endswith "nodies.app"
or RemoteUrl endswith "tenderly.co"
or RemoteUrl endswith "1rpc.io"
or RemoteUrl endswith "drpc.org"
or RemoteUrl endswith "publicnode.com"
or RemoteUrl endswith "ankr.com"
or RemoteUrl endswith "quiknode.pro"
or RemoteUrl endswith "blastapi.io"
)
| summarize PriorRpcEvents=count() by DeviceId;
let follow_on =
DeviceNetworkEvents
| where Timestamp >= ago(current_window)
| where isnotempty(RemoteUrl)
| where isnotempty(InitiatingProcessUniqueId)
| where not((
RemoteUrl endswith "nodies.app"
or RemoteUrl endswith "tenderly.co"
or RemoteUrl endswith "1rpc.io"
or RemoteUrl endswith "drpc.org"
or RemoteUrl endswith "publicnode.com"
or RemoteUrl endswith "ankr.com"
or RemoteUrl endswith "quiknode.pro"
or RemoteUrl endswith "blastapi.io"
))
| project
FollowTime=Timestamp,
DeviceId,
ProcessUniqueId=InitiatingProcessUniqueId,
FollowUrl=tolower(RemoteUrl),
FollowIP=RemoteIP,
FollowPort=RemotePort;
recent_rpc
| join kind=leftouter prior_rpc on DeviceId
| extend PriorRpcEvents=coalesce(PriorRpcEvents, 0)
| where PriorRpcEvents == 0
| join kind=inner follow_on on DeviceId, ProcessUniqueId
| where FollowTime between (RpcTime .. RpcTime + 5m)
| where FollowUrl != RpcUrl
| extend TimeDelta=FollowTime-RpcTime
| summarize arg_min(TimeDelta, *) by DeviceId, ProcessUniqueId, RpcTime
| project
RpcTime,
FollowTime,
TimeDelta,
DeviceName,
AccountUpn,
ProcessName,
ProcessCommandLine,
RpcUrl,
RpcIP,
RpcPort,
FollowUrl,
FollowIP,
FollowPort,
PriorRpcEvents
| order by RpcTime descSPL
index=<endpoint_network_index> sourcetype=<endpoint_network_events_sourcetype>
earliest=-30d
| eval
device=coalesce(device, dest, host, DeviceName),
user=lower(coalesce(user, AccountUpn, InitiatingProcessAccountUpn)),
process_name=lower(coalesce(process_name, InitiatingProcessFileName)),
process_command_line=coalesce(process_command_line, InitiatingProcessCommandLine),
process_uid=coalesce(process_uid, ProcessUniqueId, InitiatingProcessUniqueId),
remote_domain=lower(coalesce(remote_domain, RemoteUrl, dest_host)),
remote_ip=coalesce(remote_ip, RemoteIP, dest_ip),
remote_port=coalesce(remote_port, RemotePort, dest_port)
| where isnotnull(device) AND isnotnull(process_uid) AND isnotnull(remote_domain)
| eval
is_rpc=if(match(
remote_domain,
"(?i)(nodies\.app|tenderly\.co|1rpc\.io|drpc\.org|publicnode\.com|ankr\.com|quiknode\.pro|blastapi\.io)$"
),1,0),
is_runtime=if(process_name IN (
"python.exe","pythonw.exe","node.exe","powershell.exe","pwsh.exe",
"mshta.exe","wscript.exe","cscript.exe","rundll32.exe","curl.exe"
),1,0),
is_current=if(_time>=relative_time(now(),"-1d"),1,0)
| eventstats
count(eval(is_rpc=1 AND is_current=0)) as prior_rpc_events
by device
| sort 0 device process_uid _time
| streamstats current=f
last(eval(if(is_rpc=1 AND is_current=1 AND is_runtime=1,_time,null()))) as rpc_time
last(eval(if(is_rpc=1 AND is_current=1 AND is_runtime=1,remote_domain,null()))) as rpc_domain
last(eval(if(is_rpc=1 AND is_current=1 AND is_runtime=1,remote_ip,null()))) as rpc_ip
last(eval(if(is_rpc=1 AND is_current=1 AND is_runtime=1,process_name,null()))) as rpc_process
last(eval(if(is_rpc=1 AND is_current=1 AND is_runtime=1,process_command_line,null()))) as rpc_command
by device process_uid
| where
is_current=1
AND is_rpc=0
AND prior_rpc_events=0
AND isnotnull(rpc_time)
AND _time>=rpc_time
AND _time<=rpc_time+300
| eval delta_seconds=_time-rpc_time
| table
rpc_time _time delta_seconds device user process_uid
rpc_process rpc_command rpc_domain rpc_ip
remote_domain remote_ip remote_port prior_rpc_events
| sort - rpc_timeWhat to look for
A device with no prior RPC history where Python, Node, PowerShell, a script host, or another native runtime contacts an RPC provider and then reaches a separate destination from the same process.
Technical details
Tested signal
First-seen blockchain RPC activity from a scripting/runtime process followed by same-process network activity to a non-RPC destination.
Assumptions
- Defender for Endpoint retains DeviceNetworkEvents with InitiatingProcessUniqueId.
- The organization can maintain a bounded list of public blockchain RPC providers relevant to its environment.
- Thirty days is sufficient to identify endpoints with expected recurring Web3/RPC use.
Data requirements and relevant fields
- network
Endpoint network telemetry with destination, initiating process, device, user, port, and stable initiating-process identity.
TimestampDeviceIdDeviceNameRemoteIPRemotePortRemoteUrlProtocolInitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueIdInitiatingProcessAccountUpn
KQL schema
Uses documented Microsoft Defender XDR DeviceNetworkEvents/DeviceProcessEvents fields. Validate Defender for Endpoint coverage and local retention.
SPL schema
Replace index/sourcetype placeholders and normalize endpoint process/network fields to the local data source.
Limitations
- Legitimate blockchain development, wallets, monitoring, or automation can generate RPC traffic.
- The primary analytic intentionally prioritizes scripting/runtime processes and can miss browser-only EtherHiding.
- Public RPC services are legitimate infrastructure and must not be treated as malicious indicators by themselves.
The RPC provider list is an environment-maintained category, not an IOC blocklist. The five-minute follow-on correlation is intended to surface resolver-to-next-stage behavior and should be tuned using local Web3 usage.
Analyst workflow
What the analyst should look for
- Does this device normally use blockchain or Web3 services?
- Is the initiating process expected to access an RPC endpoint?
- Is the process part of approved developer tooling, wallet software, monitoring, or automation?
- What destination did the same process contact immediately after the RPC request?
- Was the follow-on destination new for the device or organization?
- What parent process launched the runtime?
- Does the command line contain a contract address, JSON-RPC method, or encoded resolver logic?
- Do other devices show the same RPC-to-follow-on sequence?
- Do source-reported contract or second-stage artifacts appear elsewhere?
Expected result
A device with no prior RPC history where Python, Node, PowerShell, a script host, or another native runtime contacts an RPC provider and then reaches a separate destination from the same process.
Investigation pivots
Drilldowns
View query — Inventory RPC activity on the candidate device
Q-02DrilldownInventory RPC activity on the candidate device
What this checks
List all blockchain RPC destinations and initiating processes seen on the candidate device around the detection.
KQL
let target_device = "<device_name>";
let pivot_time = datetime(<YYYY-MM-DDTHH:MM:SSZ>);
DeviceNetworkEvents
| where Timestamp between (pivot_time - 15m .. pivot_time + 15m)
| where DeviceName =~ target_device
| where isnotempty(RemoteUrl)
| where (
RemoteUrl endswith "nodies.app"
or RemoteUrl endswith "tenderly.co"
or RemoteUrl endswith "1rpc.io"
or RemoteUrl endswith "drpc.org"
or RemoteUrl endswith "publicnode.com"
or RemoteUrl endswith "ankr.com"
or RemoteUrl endswith "quiknode.pro"
or RemoteUrl endswith "blastapi.io"
)
| project
Timestamp,
DeviceName,
InitiatingProcessAccountUpn,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessUniqueId,
RemoteUrl,
RemoteIP,
RemotePort,
Protocol
| order by Timestamp ascSPL
index=<endpoint_network_index> sourcetype=<endpoint_network_events_sourcetype>
earliest=<pivot_minus_15m> latest=<pivot_plus_15m>
| eval
device=coalesce(device, dest, host, DeviceName),
user=lower(coalesce(user, AccountUpn, InitiatingProcessAccountUpn)),
process_name=lower(coalesce(process_name, InitiatingProcessFileName)),
process_command_line=coalesce(process_command_line, InitiatingProcessCommandLine),
process_uid=coalesce(process_uid, ProcessUniqueId, InitiatingProcessUniqueId),
remote_domain=lower(coalesce(remote_domain, RemoteUrl, dest_host)),
remote_ip=coalesce(remote_ip, RemoteIP, dest_ip),
remote_port=coalesce(remote_port, RemotePort, dest_port)
| where device="<device_name>"
| where match(
remote_domain,
"(?i)(nodies\.app|tenderly\.co|1rpc\.io|drpc\.org|publicnode\.com|ankr\.com|quiknode\.pro|blastapi\.io)$"
)
| fields _time device user process_name process_command_line process_uid remote_domain remote_ip remote_port
| sort 0 _timeWhat to look for
A bounded timeline of RPC usage showing whether the behavior is isolated, recurring, browser-driven, or tied to a scripting runtime.
Technical details
Tested signal
Blockchain RPC destinations contacted by any process on the candidate device.
Assumptions
- Replace the target device and pivot time with the values returned by Q-01.
Data requirements and relevant fields
- network
Endpoint network telemetry with destination, initiating process, device, user, port, and stable initiating-process identity.
TimestampDeviceIdDeviceNameRemoteIPRemotePortRemoteUrlProtocolInitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueIdInitiatingProcessAccountUpn
KQL schema
Uses documented Microsoft Defender XDR DeviceNetworkEvents/DeviceProcessEvents fields. Validate Defender for Endpoint coverage and local retention.
SPL schema
Replace index/sourcetype placeholders and normalize endpoint process/network fields to the local data source.
Limitations
- Endpoint network telemetry does not expose the JSON-RPC request body, so it cannot by itself prove that the method was eth_call.
KQL uses Microsoft Defender XDR endpoint telemetry. SPL is a normalized raw-event scaffold and requires local endpoint/network field mapping.
View query — Rebuild the same-process network chain
Q-03DrilldownRebuild the same-process network chain
What this checks
Show every network destination reached by the exact process that generated the candidate, before and after its RPC connection.
KQL
let target_device_id = "<device_id>";
let target_process_uid = "<process_unique_id>";
let pivot_time = datetime(<YYYY-MM-DDTHH:MM:SSZ>);
DeviceNetworkEvents
| where Timestamp between (pivot_time - 10m .. pivot_time + 10m)
| where DeviceId == target_device_id
| where InitiatingProcessUniqueId == target_process_uid
| project
Timestamp,
DeviceName,
InitiatingProcessAccountUpn,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessUniqueId,
RemoteUrl,
RemoteIP,
RemotePort,
Protocol
| order by Timestamp ascSPL
index=<endpoint_network_index> sourcetype=<endpoint_network_events_sourcetype>
earliest=<pivot_minus_10m> latest=<pivot_plus_10m>
| eval
device_id=coalesce(device_id, DeviceId),
process_uid=coalesce(process_uid, ProcessUniqueId, InitiatingProcessUniqueId),
process_name=coalesce(process_name, InitiatingProcessFileName),
process_command_line=coalesce(process_command_line, InitiatingProcessCommandLine),
remote_domain=coalesce(remote_domain, RemoteUrl, dest_host),
remote_ip=coalesce(remote_ip, RemoteIP, dest_ip),
remote_port=coalesce(remote_port, RemotePort, dest_port)
| where device_id="<device_id>" AND process_uid="<process_unique_id>"
| fields _time device_id process_uid process_name process_command_line remote_domain remote_ip remote_port
| sort 0 _timeWhat to look for
A short sequence showing RPC access followed by one or more new external destinations from the same process.
Technical details
Tested signal
Network sequence for one InitiatingProcessUniqueId around the detection pivot.
Assumptions
- The Q-01 candidate includes DeviceId and ProcessUniqueId.
Data requirements and relevant fields
- network
Endpoint network telemetry with destination, initiating process, device, user, port, and stable initiating-process identity.
TimestampDeviceIdDeviceNameRemoteIPRemotePortRemoteUrlProtocolInitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueIdInitiatingProcessAccountUpn
KQL schema
Uses documented Microsoft Defender XDR DeviceNetworkEvents/DeviceProcessEvents fields. Validate Defender for Endpoint coverage and local retention.
SPL schema
Replace index/sourcetype placeholders and normalize endpoint process/network fields to the local data source.
Limitations
- Some endpoint sources do not preserve a stable process unique identifier; fall back to device plus PID plus process creation time when necessary.
KQL uses Microsoft Defender XDR endpoint telemetry. SPL is a normalized raw-event scaffold and requires local endpoint/network field mapping.
View query — Inspect the initiating process ancestry
Q-04DrilldownInspect the initiating process ancestry
What this checks
Recover the candidate runtime process, its parent, command line, user context, path, and hashes.
KQL
let target_device_id = "<device_id>";
let target_process_uid = "<process_unique_id>";
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where DeviceId == target_device_id
| where ProcessUniqueId == target_process_uid
| project
Timestamp,
DeviceName,
AccountUpn,
FileName,
FolderPath,
ProcessCommandLine,
ProcessId,
ProcessUniqueId,
SHA1,
SHA256,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessId,
InitiatingProcessUniqueId
| order by Timestamp ascSPL
index=<endpoint_process_index> sourcetype=<process_events_sourcetype>
earliest=-7d
| eval
device_id=coalesce(device_id, DeviceId),
process_uid=coalesce(process_uid, ProcessUniqueId),
user=lower(coalesce(user, AccountUpn)),
process_name=coalesce(process_name, FileName),
process_path=coalesce(process_path, FolderPath),
process_command_line=coalesce(process_command_line, ProcessCommandLine),
parent_process_name=coalesce(parent_process_name, InitiatingProcessFileName),
parent_command_line=coalesce(parent_command_line, InitiatingProcessCommandLine),
sha1=coalesce(sha1, SHA1),
sha256=coalesce(sha256, SHA256)
| where device_id="<device_id>" AND process_uid="<process_unique_id>"
| fields _time device_id user process_name process_path process_command_line process_uid parent_process_name parent_command_line sha1 sha256
| sort 0 _timeWhat to look for
The executable and ancestry that explain whether RPC access came from expected developer tooling, a browser-adjacent runtime, or an unusual loader.
Technical details
Tested signal
Process creation event matching the network event's stable process identity.
Assumptions
- The network candidate includes DeviceId and InitiatingProcessUniqueId.
Data requirements and relevant fields
- process
Endpoint process telemetry with process identity, command line, parent context, user, and hashes.
TimestampDeviceIdDeviceNameFileNameFolderPathProcessIdProcessUniqueIdProcessCommandLineAccountUpnSHA1SHA256InitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueId
KQL schema
Uses documented Microsoft Defender XDR DeviceNetworkEvents/DeviceProcessEvents fields. Validate Defender for Endpoint coverage and local retention.
SPL schema
Replace index/sourcetype placeholders and normalize endpoint process/network fields to the local data source.
Limitations
- Short-lived processes can be absent if process telemetry was not retained at the candidate time.
KQL uses Microsoft Defender XDR endpoint telemetry. SPL is a normalized raw-event scaffold and requires local endpoint/network field mapping.
View query — Search source-reported EtherHiding artifacts
Q-05DrilldownSearch source-reported EtherHiding artifacts
What this checks
Check the candidate environment for the Polygon contract, method selector, and malicious second-stage domain reported in Cribl's August 2026 investigation.
KQL
let reported_contract = "0x0C7Cb01C83203aC0a50Abc3a9AFF3c9Ca727eF55";
let reported_selector = "b68d1809";
let reported_second_stage = "thu-ipad-03.cfd";
union
(
DeviceNetworkEvents
| where Timestamp >= ago(30d)
| where RemoteUrl =~ reported_second_stage
| project
Timestamp,
DeviceName,
ArtifactType="Network",
ArtifactValue=RemoteUrl,
ProcessName=InitiatingProcessFileName,
ProcessCommandLine=InitiatingProcessCommandLine,
AccountUpn=InitiatingProcessAccountUpn
),
(
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where ProcessCommandLine has reported_contract
or ProcessCommandLine has reported_selector
| project
Timestamp,
DeviceName,
ArtifactType="Process",
ArtifactValue=ProcessCommandLine,
ProcessName=FileName,
ProcessCommandLine,
AccountUpn
)
| order by Timestamp ascSPL
(
index=<endpoint_network_index> sourcetype=<endpoint_network_events_sourcetype> earliest=-30d
"thu-ipad-03.cfd"
)
OR
(
index=<endpoint_process_index> sourcetype=<process_events_sourcetype> earliest=-30d
("0x0C7Cb01C83203aC0a50Abc3a9AFF3c9Ca727eF55" OR "b68d1809")
)
| eval
device=coalesce(device, dest, host, DeviceName),
user=lower(coalesce(user, AccountUpn, InitiatingProcessAccountUpn)),
process_name=coalesce(process_name, FileName, InitiatingProcessFileName),
process_command_line=coalesce(process_command_line, ProcessCommandLine, InitiatingProcessCommandLine),
artifact=coalesce(RemoteUrl, remote_domain, process_command_line)
| fields _time device user process_name process_command_line artifact
| sort 0 _timeWhat to look for
Another device or process references the reported contract/selector or reaches the reported second-stage domain.
Technical details
Tested signal
Source-scoped contract or second-stage artifacts appear in process or network telemetry.
Assumptions
- The source-reported values are used for retrospective scoping, not as universal EtherHiding requirements.
Data requirements and relevant fields
- network
Endpoint network telemetry with destination, initiating process, device, user, port, and stable initiating-process identity.
TimestampDeviceIdDeviceNameRemoteIPRemotePortRemoteUrlProtocolInitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueIdInitiatingProcessAccountUpn
- process
Endpoint process telemetry with process identity, command line, parent context, user, and hashes.
TimestampDeviceIdDeviceNameFileNameFolderPathProcessIdProcessUniqueIdProcessCommandLineAccountUpnSHA1SHA256InitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueId
KQL schema
Uses documented Microsoft Defender XDR DeviceNetworkEvents/DeviceProcessEvents fields. Validate Defender for Endpoint coverage and local retention.
SPL schema
Replace index/sourcetype placeholders and normalize endpoint process/network fields to the local data source.
Limitations
- A negative IOC search does not weaken the EtherHiding hypothesis because contracts, selectors, chains, and follow-on domains can rotate.
- The public RPC providers in the source report are legitimate infrastructure and should not be blocked globally.
KQL uses Microsoft Defender XDR endpoint telemetry. SPL is a normalized raw-event scaffold and requires local endpoint/network field mapping.
Legitimate resemblance
What the analyst should confirm
A developer workstation runs Python or Node against public Polygon, Ethereum, Base, or other EVM RPC services during approved blockchain development.
The device belongs to an approved Web3/development population, the runtime path and code repository are expected, the RPC providers match the project, and follow-on destinations are documented dependencies.An approved monitoring or blockchain analytics agent queries public RPC endpoints and then reaches its own backend or telemetry service.
The process signer/path, service owner, deployment record, recurring schedule, endpoint population, and follow-on backend all match the approved product.A security researcher or sandbox intentionally analyzes blockchain-backed malware and queries a source-reported contract.
The activity occurs on an isolated research system, matches a documented analysis window, and does not progress into unexplained persistence or credential access.
Confirmed match
Action after a confirmed match
- Isolate an endpoint when the resolver chain is tied to confirmed malware execution.
- Block confirmed malicious follow-on infrastructure, not legitimate public RPC services as a blanket action.
- Collect the initiating script/binary and preserve its command line, hashes, and parent lineage.
- Search the environment for the same contract address, selector, second-stage infrastructure, and resolver behavior.
- Review persistence, credential access, and outbound C2 activity associated with the affected process.
- Restrict or monitor public blockchain RPC access on endpoint populations that have no business requirement.
Threat hunt
Could this be happening elsewhere?
Hunt for this behavior across the environment.Technical boundary
Telemetry and limitations
- Network
Endpoint network telemetry with destination, initiating process, device, user, port, and stable initiating-process identity.
Required fieldsTimestampDeviceIdDeviceNameRemoteIPRemotePortRemoteUrlProtocolInitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueIdInitiatingProcessAccountUpn
- Process
Endpoint process telemetry with process identity, command line, parent context, user, and hashes.
Required fieldsTimestampDeviceIdDeviceNameFileNameFolderPathProcessIdProcessUniqueIdProcessCommandLineAccountUpnSHA1SHA256InitiatingProcessFileNameInitiatingProcessCommandLineInitiatingProcessIdInitiatingProcessUniqueId
Blind spots
- The primary detection intentionally prioritizes scripting/runtime processes and can miss browser-only EtherHiding used by compromised websites.
- DeviceNetworkEvents does not expose JSON-RPC request bodies, so the analytic cannot directly confirm an eth_call or contract address from network metadata alone.
- Private, self-hosted, newly created, or unlisted RPC gateways can evade a provider-category filter.
- If the same process identifier is not retained across network events, same-process correlation must fall back to device, PID, and process creation time.
- A contract can return a full payload or a pointer, and the follow-on sequence can vary by chain and campaign.
Behavior mapping
MITRE ATT&CK
T1102.001· Dead Drop ResolverEtherHiding uses legitimate public Web3/RPC infrastructure as a dead-drop resolver for secondary C2 or payload information.
T1105· Ingress Tool TransferReported EtherHiding chains can use the resolved value to retrieve or execute follow-on content.
Mappings describe the behavior examined by this analytic. They do not prove attribution, deployment, or technique-wide coverage.
Review boundary
Sources and limits
- External sources
- 5
Exact fields, retention, and operational thresholds remain environment-specific.