---
title: "Threat Hunt Plan: Node-RED Missing Authentication on Siemens SIMATIC IoT2050 Advanced — Unauthenticated RCE and Linux Malware Deployment"
description: This hunt searches for exploitation of the missing-authentication vulnerability in the Node-RED programming environment shipped with Siemens SIMATIC IoT2050 Advanced gateways
---

[Skip to content](https://1898advisories.burnsmcd.com/threat-hunt-plan-node-red-missing-authentication-on-siemens-simatic-iot2050-advanced-unauthenticated-rce-and-linux-malware-deployment#main-content)

![1898-logo-grey-R-1](https://1898advisories.burnsmcd.com/hs-fs/hubfs/1898-logo-grey-R-1.webp?width=188&height=100&name=1898-logo-grey-R-1.webp)

- [Cyberthreat](https://1898advisories.burnsmcd.com/tag/cyberthreat)
- [Threat Hunt](https://1898advisories.burnsmcd.com/tag/threat-hunt)
- [View All](https://1898advisories.burnsmcd.com/)

Open main navigation

Close main navigation

- [Cyberthreat](https://1898advisories.burnsmcd.com/tag/cyberthreat)
- [Threat Hunt](https://1898advisories.burnsmcd.com/tag/threat-hunt)
- [View All](https://1898advisories.burnsmcd.com/)
- [Contact us](https://1898andco.burnsmcd.com/contact-us)

[Contact us](https://1898andco.burnsmcd.com/contact-us)

 November 4, 2026

# Threat Hunt Plan: Node-RED Missing Authentication on Siemens SIMATIC IoT2050 Advanced — Unauthenticated RCE and Linux Malware Deployment

![Picture of The 1898 & Co. Team](https://1898advisories.burnsmcd.com/hs-fs/hubfs/1898%20Cyberthreat%20Advisory%20Blog%20Assets/1898-Co-Ampersand.png?width=50&name=1898-Co-Ampersand.png) [The 1898 & Co. Team](https://1898advisories.burnsmcd.com/author/1898-co-team)

Date: 2026-11-04 | Revision 1.0

#### Hunt Objective and Scope

This hunt searches for exploitation of the missing-authentication vulnerability in the Node-RED programming environment shipped with Siemens SIMATIC IoT2050 Advanced gateways (CVE-2026-58115, CVSS v3.1 10.0 / CVSS v4.0 10.0, CWE-306). The objective is to determine whether any internet-reachable or internally-reachable SIMATIC IoT2050 Advanced device running Industrial OS with Node-RED installed has had its unauthenticated Node-RED HTTP interface abused to deploy a malicious flow, download and execute a Linux bot binary, or serve as a pivot into the control environment. In scope: all SIMATIC IoT2050 Advanced gateways (article number 6ES7647-0BA00-1YA2) at Industrial OS versions below V4.3.4.1, the network segments those gateways bridge, and any host that initiated connections to or received connections from a gateway during the window.

Time window: 2026-08-11 (the date Siemens published SSA-834709, after which the missing-authentication condition was publicly known and opportunistic exploitation became plausible) through the present. Confirmed in-the-wild activity against this CVE was first observed on 2026-10-30; treat the full window as the hunt horizon rather than starting at that date, because scanning may have preceded the first public report.

Data floor pre-flight (mandatory before any event-based leg runs): measure the data floor — the oldest retained event per family and record the floor DATE, never a duration — a time picker is not retention. Run in CrowdStrike Falcon LogScale:

`#event_simpleName=/^(ProcessRollup2|NetworkConnectIP4|NetworkReceiveAcceptIP4|NewExecutableWritten|DnsRequest)$/ | groupBy([#event_simpleName], function=min(@timestamp, as=oldest), limit=max)`

 

The portion of the window earlier than the measured floor is Non-Conclusive for every event-based clause (connection records, process executions, file writes). State-based clauses — the installed Industrial OS version, the current Node-RED flow set, a dropped binary still present on disk, a hidden file still in /dev/shm or /tmp — describe conditions that exist now and can be re-queried as current state regardless of the floor; each hypothesis below states which kind it is.

#### Hypotheses and Hunt Procedures

Hypothesis 1 (EXECUTE FIRST): An external actor can reach an internet-facing SIMATIC IoT2050 / Node-RED instance, observable as an exposed Node-RED HTTP service in passive internet-scan indices. Its output scopes the internal hypotheses — a confirmed-owned, in-range exposed instance converts the internal hunt for that device from sampling into an exhaustive pass. This is a state-based hypothesis (current exposure).

**MITRE ATT&CK:** Reconnaissance | T1595 Active Scanning (defender-side: passive discovery of what an actor would enumerate) · Initial Access | T1133 External Remote Services · ICS | T0883 Internet Accessible Device — an exposed Node-RED editor is the exact entry point this campaign uses.

**Collection Queries** — passive external indices (STRICTLY passive; never probe target infrastructure). Author unscoped first (proves the filter matches the product), then scoped with your own public ranges. API keys are referenced by env-var name only (SHODAN\_API\_KEY, CENSYS\_API\_SECRET, CENSYS\_ORG\_ID, NETLAS\_API\_KEY) and never inlined.

`Shodan: product:"Node-RED" http.title:"Node-RED" port:1880 "Node-RED" // scope to your estate (use ONE anchor per query; never AND two ownership anchors): product:"Node-RED" net:<your_public_CIDR> product:"Node-RED" org:"<Your Org Name>" product:"Node-RED" asn:AS<your_ASN>`

 

`Censys (CenQL — current host.services form; do NOT cross with legacy services.* CSL): host.services.software.product: "Node-RED" host.services: (port = "1880" and endpoints.http.html_title: "Node-RED") // scope: host.services.software.product: "Node-RED" and (host.autonomous_system.asn = <your_ASN> or host.ip: "<your_public_CIDR>")`

 

`Netlas: http.title:"Node-RED" host:<your_public_CIDR> AND port:(1880 OR 443 OR 80)`

 

`→ Cross-reference every exposed service against the CISA Known Exploited Vulnerabilities catalog (https://www.cisa.gov/known-exploited-vulnerabilities-catalog) and CVE-2026-58115; a KEV match is a presumptive actor-associated initial-access risk. Rank by ransomware ratio, not entry count.`

 

`→ Expected Positive shape: a host in one of your declared public ranges returning a Node-RED editor banner / HTML title on 1880 (or behind 80/443), attributable to your org by ≥2 independent ownership signals.`

 

Favicon-hash pivoting: Node-RED on a non-standard port or behind a reverse proxy may strip the banner. Derive the favicon hash passively from a Node-RED instance you own (reuse an index-computed hash) — never fetch /favicon.ico from a target, and never copy a hash from a write-up.

**Analysis Queries:**

`- Attribute each hit with ≥2 independent ownership signals (PTR, ASN, cert CN/SAN, WHOIS/RDAP, your own cloud inventory) before reporting. Shared hosting and CDN break attribution both ways; an unattributable hit is Non-Conclusive, not negative. - Version-triage each banner and record the index scan timestamp — a banner is stale in both directions. - Corroborate in ≥2 of Shodan / Censys / Netlas before escalating; absence from one index only means that index did not observe the host. - Historical pivot: establish whether the exposure spans 2026-08-11 → present; continuous exposure across the window means presumptively enumerated. - Pivot: feed every confirmed-owned, in-range instance into Hypotheses 2–4 as a priority target and hunt it exhaustively.`

 

**Control** — unscoped filter proves the engine matches the product: run product:"Node-RED" (Shodan) and host.services.software.product: "Node-RED" (Censys) with NO ownership anchor and confirm non-zero global results before trusting any scoped zero. A scoped zero with a zero unscoped control is Non-Conclusive (likely a crossed CenQL/CSL field form or a missing key), never Negative.

**Verdict criteria:** Positive — a Node-RED/IoT2050 service in a declared public range, attributed by ≥2 signals, corroborated in ≥2 engines; Negative — no exposed instance in any declared range AND the unscoped control non-zero AND the public-IP/cloud inventory complete; Non-Conclusive — unscoped control zero, incomplete public-IP inventory, or unattributable hit; missing authoritative public-IP + cloud inventory prevents determining whether an observed host is ours.

**Hypothesis 2:** An unauthenticated attacker has reached the Node-RED admin HTTP interface on a SIMATIC IoT2050 Advanced gateway and deployed a malicious flow, observable as POST requests to the /flows admin endpoint and the appearance of unexpected inject, exec, or http-in nodes. Event-based for the request traffic; state-based for the current flow set.

**MITRE ATT&CK:** Initial Access | T1190 Exploit Public-Facing Application | the unauthenticated Node-RED HTTP interface is the public-facing application exploited. Execution | T1059 Command and Scripting Interpreter | a malicious flow chains an exec node to run OS commands.

**Collection Queries:**

**CrowdStrike Falcon LogScale** (CQL) — inbound connections to the Node-RED port on the gateway, where the gateway carries the Falcon Linux sensor (note the coverage gap below if it does not):

`#event_simpleName=NetworkReceiveAcceptIP4 event_platform=Lin | LocalPort=1880 | table([aid, ComputerName, LocalAddressIP4, LocalPort, RemoteAddressIP4, RemotePort], limit=20000)`

 

`→ Expected Positive shape: inbound accepts on LocalPort 1880 from an external or non-engineering RemoteAddressIP4, especially the scanner address 4.201.105.116.`

 

**BPF packet capture** (VLAN-aware, two-branch — 802.1Q tags are frequently present on OT access links; an untagged filter alone can match 0). Capture Node-RED admin traffic to/from the gateway:

`tcp​dump -i <iface>​ -w /captures/nodered_%Y%m%d_%H%M%S.pcap -G 3600 -C 100 '(host <gateway_ip> and tcp port 1880) or (vlan and host <gateway_ip> and tcp port 1880)'`

 

**Datadog Log Search** (where the gateway or a reverse proxy forwards Node-RED/HTTP access logs; positive term required so a log merely lacking the attribute does not satisfy the filter):

`source:syslog @http.url_details.path:"/flows" @http.method:POST // time range: 2026-08-11T00:00Z to current // Fallback if HTTP access logs are not parsed: source:syslog "POST /flows" host:<gateway_host>`

 

`Datadog Live Process Monitoring (Infrastructure > Processes — NOT a log source) on the gateway, to catch node-red spawning a shell: command:node user:root`

 

**OT/ICS Data Collection** — scope to the gateway population and pull its admin-interface reachability on every deployed platform:

`OT Data Collection: Claroty xDome — in Communication Analysis, filter one side to the gateway IP list and Port = 1880; export the peer set that reached the Node-RED interface (segment by site; the export ceiling is 100,000 records). Scope the external-vector clause by network/VLAN, not by Category. OT Data Collection: Dragos Platform — Communications Hub: source-zone = any external/enterprise zone AND dest = the gateway asset AND port = 1880 over the window → pivot each session to its asset record and event PCAP. OT Data Collection: Nozomi Guardian — Link view filtered to the gateway node and protocol/port 1880; export the PCAP attached to any related alert and run it offline through pcap_analyzer.py. OT Data Collection: Armis Centrix — enumerate the gateway population and its server-side Node-RED sessions: in:devices brand:Siemens in:ipConnections role:Server serverPort:1880 OT Data Collection: Tenable OT — Inventory → All Assets: filter AssetType in (IndustrialGateway) and vendor = Siemens; carry the gateway list forward, then review Events for the window. OT Data Collection: Forescout eyeInspect — Command Center → Alerts filtered to the gateway host_id and the hunt window; group by event_type_names and src_ip; retrieve the PCAP for each matching alert_id.`

 

YARA (file-system scan for a planted malicious flow definition on the gateway filesystem or a backup of it):

`ya​ra -r rules/nodered_malicious_flow.yar /opt/ /home/ /data/ >​>​ hits_nodered_flow.txt`

 

**Analysis Queries:**

**CrowdStrike Falcon LogScale** (CQL) — rank inbound sources to the Node-RED port, rarest-first to surface one-off scanners:

`#event_simpleName=NetworkReceiveAcceptIP4 event_platform=Lin | LocalPort=1880 | groupBy([RemoteAddressIP4], function=count(as=hits), limit=100000) | sort(hits, order=asc, limit=100)`

 

`CrowdStrike Falcon LogScale (CQL) — Node-RED process spawning a shell or downloader (malicious-flow exec node): #event_simpleName=ProcessRollup2 event_platform=Lin | ParentBaseFileName=/node/i | ImageFileName=/\/(sh|bash|wget|curl)$/i | table([aid, ComputerName, ImageFileName, CommandLine, ParentBaseFileName], limit=20000)`

 

Wireshark display filter (Node-RED admin API is plaintext HTTP on 1880 by default — no decryption needed; an IDS/analysis sees the URI directly):

`http.request.method == "POST" && http.request.uri contains "/flows" && tcp.port == 1880 tshark -r nodered.pcap -Y 'http.request.method == "POST" && http.request.uri contains "/flows"' -T fields -e ip.src -e ip.dst -e http.request.uri`

 

**Datadog Log Analytics:** Use Table view; group by @network.client.ip; time range 2026-08-11 to current; base query source:syslog @http.url\_details.path:"/flows" @http.method:POST. Datadog Monitor:

`Type: Log Alert Query: source:syslog @http.url_details.path:"/flows" @http.method:POST Evaluation window: last 5 minutes Alert condition: count > 0 Message: "ALERT: POST to Node-RED /flows admin endpoint on an IoT2050 gateway — possible CVE-2026-58115 flow injection, investigate immediately @soc-oncall" Prerequisites: gateway/reverse-proxy HTTP access logs forwarded to Datadog and the path/method attributes parsed`

 

**Control** — NetworkReceiveAcceptIP4 field/family presence on Linux: a zero inbound result is only meaningful if the gateway reports inbound telemetry at all.

`#event_simpleName=NetworkReceiveAcceptIP4 event_platform=Lin | LocalPort=/./ | count()`

 

Coverage gap to state next to every CQL leg here: the SIMATIC IoT2050 runs Industrial OS (Debian-based); if the CrowdStrike Falcon Linux sensor is not installed on the gateway, the device emits no CQL telemetry of its own and these legs report Non-Conclusive — fall back to the OT-platform flow records, the reverse-proxy logs, and PCAP.

**Verdict criteria:** Positive — POST /flows from a non-engineering source OR an unexpected inject/exec/http-in node present in the current flow set on an affected gateway; Negative — no POST /flows in the window AND no unaccounted node in the current flows AND the NetworkReceiveAcceptIP4 control non-zero (or OT-platform flow coverage confirmed); Non-Conclusive — gateway lacks the Falcon sensor and neither OT-platform flow records nor access logs cover it; missing Node-RED access logging prevents determining whether the admin endpoint was reached.

**Hypothesis 3:** A compromised gateway has downloaded and executed a Linux bot payload, observable as a shell/downloader writing an executable into /dev/shm or /tmp (e.g. bot-linux-amd64 to /dev/shm/.b), that executable running, and an outbound connection to the payload-hosting server. Event-based for the download/execution; state-based for a dropped binary or hidden file still present.

**MITRE ATT&CK:** Command and Control | T1105 Ingress Tool Transfer | the flow downloads bot-linux-amd64 from an external host. Execution | T1059.004 Unix Shell | the exec node runs a shell command. Defense Evasion | T1564.001 Hidden Files and Directories | the payload is written as a dot-file (.b) in memory-backed /dev/shm.

**Collection Queries:**

**CrowdStrike Falcon LogScale** (CQL) — executable written into a memory-backed or temp directory on Linux:

`#event_simpleName=NewExecutableWritten event_platform=Lin | TargetFileName=/\/(dev\/shm|tmp)\//i | table([aid, ComputerName, TargetFileName, ContextProcessId], limit=20000)`

 

`CrowdStrike Falcon LogScale (CQL) — process execution referencing the known payload artifacts: #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(bot-linux-amd64|wget\.sh|\/dev\/shm\/\.b|\.kworker)/i | table([aid, ComputerName, ImageFileName, CommandLine, ParentBaseFileName], limit=20000)`

 

`CrowdStrike Falcon LogScale (CQL) — outbound connection to the payload host: #event_simpleName=NetworkConnectIP4 event_platform=Lin | cidr(RemoteAddressIP4, subnet=["85.215.73.250/32"]) | table([aid, ComputerName, LocalAddressIP4, RemoteAddressIP4, RemotePort, ContextProcessId], limit=20000)`

 

**BPF packet capture** (VLAN-aware, two-branch) — outbound retrieval from the payload host:

`tcp​dump -i <iface>​ -w /captures/payload_%Y%m%d_%H%M%S.pcap -G 3600 -C 100 '(host 85.215.73.250) or (vlan and host 85.215.73.250)'`

 

**Datadog Log Search** (gateway auditd/syslog where forwarded; positive attribute required):

`source:syslog @file.path:("/dev/shm/*" OR "/tmp/*") "bot-linux-amd64" // time range: 2026-08-11T00:00Z to current // Fallback if auditd exec logging is not parsed: source:syslog ("bot-linux-amd64" OR "/dev/shm/.b") host:<gateway_host>`

 

YARA (file-system scan for the dropped Linux bot and its staging artifacts):

`ya​ra -r rules/nodered_linux_bot_dropper.yar /dev/shm/ /tmp/ /var/tmp/ >​>​ hits_bot_dropper.txt`

 

**Analysis Queries:**

**CrowdStrike Falcon LogScale** (CQL) — attribute the outbound-to-payload-host connection to its process via the reverse-join idiom (NetworkConnectIP4 lacks ImageFileName; join from the long-lived process side):

`#event_simpleName=/ProcessRollup2/ event_platform=Lin | join(query={#event_simpleName=NetworkConnectIP4 | cidr(RemoteAddressIP4, subnet=["85.215.73.250/32"])}, field=[aid, TargetProcessId], key=[aid, ContextProcessId], include=[RemoteAddressIP4, RemotePort], limit=100000) | table([ComputerName, ImageFileName, CommandLine, RemoteAddressIP4, RemotePort], limit=max)`

 

`CrowdStrike Falcon LogScale (CQL) — rarest child processes of node across the gateway fleet (anomalous spawns): #event_simpleName=/ProcessRollup2/ event_platform=Lin | ParentBaseFileName=/node/i | groupBy([ImageFileName], function=count(as=hits), limit=100000) | sort(hits, order=asc, limit=100)`

 

**YARA memory scan** (classic YARA 4.5 takes the PID as the positional target — there is NO -p PID flag) for an executing in-memory payload on a suspect gateway:

`ya​ra rules/nodered_linux_bot_dropper.yar <suspect_pid>​ >​>​ mem_hits.txt`

 

**Wireshark display filter** — retrieval of the bot binary over HTTP:

`http.request.uri contains "bot-linux-amd64" || http.request.uri contains "wget.sh" tshark -r payload.pcap -Y 'http.request.uri contains "bot-linux-amd64"' -T fields -e ip.src -e ip.dst -e http.request.uri`

 

**Datadog Monitor:**

`Type: Log Alert Query: source:syslog ("bot-linux-amd64" OR "/dev/shm/.b") Evaluation window: last 5 minutes Alert condition: count > 0 Message: "ALERT: Linux bot payload artifact observed on an IoT2050 gateway — confirmed CVE-2026-58115 post-exploitation, isolate device @soc-oncall" Prerequisites: gateway auditd/execve logging forwarded to Datadog and file-path/command attributes parsed`

 

**Control** — ProcessRollup2 field presence on Linux (a CommandLine filter is not controlled by a bare family-presence check; count the field):

`#event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/./ | count()`

 

**Verdict criteria:** Positive — an executable written to /dev/shm or /tmp and executed on an affected gateway, OR an outbound connection from a gateway to 85.215.73.250, OR a bot artifact (bot-linux-amd64 / /dev/shm/.b / wget.sh / .kworker) present; Negative — none of these in the window AND the ProcessRollup2 CommandLine control non-zero AND a current filesystem scan clean; Non-Conclusive — gateway lacks the Falcon sensor and auditd is not forwarded; missing execve/file telemetry from the gateway prevents determining whether a payload ran.

**Hypothesis 4:** A compromised IoT2050 gateway is being used as a pivot into the control network, observable as anomalous connections originating FROM the gateway address into internal or OT segments (RDP/SSH/SMB/VNC or an industrial protocol) that are not part of its normal peer set. Event-based.

**MITRE ATT&CK:** Lateral Movement | T1021 Remote Services | the gateway, sitting at the IT/OT boundary, is used to reach deeper hosts. ICS | T0866 Exploitation of Remote Services | abuse of the gateway's legitimate reachability into the control zone. ICS | T0885 Commonly Used Port | pivoting over the protocols the gateway normally bridges.

**Collection Queries:**

**CrowdStrike Falcon LogScale** (CQL) — connections initiated FROM the gateway into internal/OT CIDRs (seen on the gateway if it has the Falcon sensor; otherwise seen as NetworkReceiveAcceptIP4 on the destination hosts):

`// Substitute the illustrative RFC1918 literals below with your gateway and OT-zone ranges before executing. #event_simpleName=NetworkConnectIP4 event_platform=Lin | cidr(LocalAddressIP4, subnet=["10.20.30.0/24"]) | cidr(RemoteAddressIP4, subnet=["10.40.0.0/16"]) | in(RemotePort, values=["22","445","3389","5900","502","102","44818","20000"]) | table([aid, ComputerName, LocalAddressIP4, RemoteAddressIP4, RemotePort], limit=20000)`

 

`CrowdStrike Falcon LogScale (CQL) — the mirror view from the destination side (no Falcon sensor on the gateway required): #event_simpleName=NetworkReceiveAcceptIP4 | cidr(RemoteAddressIP4, subnet=["10.20.30.0/24"]) | in(LocalPort, values=["22","445","3389","5900"]) | table([aid, ComputerName, LocalAddressIP4, LocalPort, RemoteAddressIP4], limit=20000)`

 

Windows Event collection (on engineering workstations / servers the gateway may reach — remote logons sourced from the gateway address):

`- 4624 (An account was successfully logged on) — filter LogonType 3/10 with IpAddress = the gateway address - 4625 (An account failed to log on) — brute-force indication from the gateway address - 5140 (A network share was accessed) — SMB access sourced from the gateway Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624,4625; StartTime=(Get-Date '2026-08-11')} | Where-Object { $_.Message -match '<gateway_ip>' } | Export-Csv -NoTypeInformation gateway_logons.csv`

 

**OT/ICS Data Collection** — cross-Purdue and anomalous-industrial-write hunting from the gateway:

`OT Data Collection: Dragos Platform — Communications Hub: source = the gateway asset AND dest-zone in the control zones AND protocol IN [RDP,SSH,VNC,SMB,Modbus,S7,EtherNet/IP] over the window; also query the Industrial Protocols QFD for unauthenticated Modbus/S7 writes outside the maintenance window and pivot each to asset + PCAP. OT Data Collection: Claroty xDome — Communication Analysis with Side A = the gateway IP list and Direction toward control-zone networks (scope by network/VLAN, not Category; Direction is an observation, not a clearance — a one-way flow does not clear the gateway). Reconcile the session/byte counts against an independent source before signing any volumetric claim. OT Data Collection: Nozomi Guardian — Variable view: review process-variable trends on controllers the gateway can reach; flag any setpoint excursion outside the learned band with no corresponding operator action during the window. OT Data Collection: Tenable OT — Events: filter Event Category = Configuration Events with event types "Change in state" and "Change in firmware version" across the window; correlate each against the change record. OT Data Collection: Forescout eyeInspect — export the host changelog filtered to the controller population; escalate any firmware_version or os_version transition with no corresponding maintenance work order.`

 

**SNMP polling** — baseline the switch port facing the gateway and the controllers it reaches (provision v3 credentials via snmp.conf, not inline, where possible):

`snmpwalk -v3 -l authPriv -u <user> -a SHA-256 -A <authpass> -x AES-256 -X <privpass> <switch_ip> IF-MIB::ifTable snmpget -v3 -l authPriv -u <user> -a SHA-256 -A <authpass> -x AES-256 -X <privpass> <switch_ip> IF-MIB::ifHCInOctets.<ifIndex> IF-MIB::ifHCOutOctets.<ifIndex> IF-MIB::ifInErrors.<ifIndex> // Repeat at 60s intervals and diff successive values; flag anomalous spikes on the gateway-facing port. Treat any v1/v2c community access to OT assets as a finding. // Collect coldStart (1.3.6.1.6.3.1.1.5.1) / warmStart (.2) traps from the trap receiver — an unexpected controller reboot during the window is an escalation.`

 

**Analysis Queries:**

**CrowdStrike Falcon LogScale** (CQL) — rarest destinations reached from the gateway (new lateral peers):

`#event_simpleName=NetworkConnectIP4 event_platform=Lin | cidr(LocalAddressIP4, subnet=["10.20.30.0/24"]) | groupBy([RemoteAddressIP4, RemotePort], function=count(as=hits), limit=100000) | sort(hits, order=asc, limit=100)`

 

`→ Expected Positive shape: a control-zone host/port the gateway has never previously contacted, reached during or after the exploitation window.`

 

**Wireshark display filter** — OT protocol pivot from the gateway (EtherNet/IP write and Modbus write as examples):

`(ip.src == <gateway_ip>) && (enip || (modbus && modbus.func_code >= 5) || s7comm) tshark -r pivot.pcap -Y '(ip.src == <gateway_ip>) && modbus.func_code >= 5' -T fields -e ip.dst -e modbus.func_code`

 

**YARA memory scan** (lateral movement / credential access — standing rule; see §5 note on Windows vs Linux scope): run against suspect engineering-workstation processes the gateway reached:

`ya​ra rules/credential_dump_memory.yar <suspect_pid>​ >​>​ cred_mem_hits.txt`

 

**Datadog Monitor:**

`Type: Log Alert Query: source:windows @evt.id:4624 @network.client.ip:<gateway_ip> (@logon.type:3 OR @logon.type:10) Evaluation window: last 10 minutes Alert condition: count > 0 Message: "ALERT: interactive/network logon sourced from an IoT2050 gateway address — possible OT pivot @soc-oncall" Prerequisites: Windows Security event logs forwarded to Datadog from the engineering hosts`

 

**Control** — NetworkConnectIP4 presence scoped to the gateway range (proves the pivot leg can observe anything at all):

`#event_simpleName=NetworkConnectIP4 event_platform=Lin | cidr(LocalAddressIP4, subnet=["10.20.30.0/24"]) | count()`

 

**Verdict criteria:** Positive — a connection from a gateway address to a control-zone host on a remote-access or industrial-control port that is not in the gateway's established baseline, OR an unexplained controller configuration/firmware change reachable from the gateway; Negative — no out-of-baseline connection from any gateway address in the window AND the NetworkConnectIP4 (or destination-side NetworkReceiveAcceptIP4) control non-zero AND OT-platform flow coverage confirmed; Non-Conclusive — neither the gateway nor the destination hosts report connection telemetry and OT-platform flow records do not cover the segment; missing gateway baseline prevents distinguishing a malicious pivot from normal bridging.

#### Threat Actor Profile

Activity observed against CVE-2026-58115 to date is consistent with opportunistic, financially-or-botnet-motivated mass scanning rather than a targeted intrusion. Independent canary telemetry recorded exploitation beginning 2026-10-30, with repeated attempts against the Node-RED flaw from a single source address over a three-day span alongside scanning of multiple unrelated CVEs — a pattern characteristic of broad internet-wide sweeping for any reachable vulnerable service, not of an actor selecting a specific plant. No named threat group, APT cluster, or ransomware affiliate has been attributed to this activity in any government or vendor advisory; it should be described as opportunistic exploitation, not attributed to any actor or government.

The access path is the vulnerability's defining feature: an unauthenticated attacker who can route to the Node-RED HTTP interface needs no credentials, no social engineering, and no second-stage exploit. Sophistication required is low — the published activity uses Node-RED's own inject-and-exec node pattern to fetch and run a payload — but the consequence is high because the exec node runs with maximum privilege on a device positioned at the IT/OT boundary. The realistic risk is twofold: immediate conscription of the gateway into a Linux botnet (the observed payload is a Linux bot binary), and the latent possibility that an opportunistic foothold on an OT-adjacent device is later recognized and escalated toward the control environment. Because the gateway legitimately bridges field devices to higher-level systems, even a botnet-grade compromise carries OT consequence that a comparable IT host would not.

Give any claim of targeting the harshest skepticism absent corroboration: a canary catching a scan is evidence of exposure and opportunistic interest, not of an actor's intent against a particular site. Treat the two observed IP addresses as campaign infrastructure of unknown longevity — the scanner source sits in a major cloud provider's address space (readily rotated) and the payload host is a download server with no confirmed command-and-control role.

#### Data Sources Required

**Network:** full-packet capture (PCAP) at the gateway uplink and the IT/OT boundary, NetFlow/IPFIX, firewall and reverse-proxy logs, and DNS query logs. Endpoint: CrowdStrike Falcon telemetry (Linux sensor on the gateway if present; Windows/Linux sensors on reachable hosts), Linux auditd/execve logs from the gateway, and Windows Security event logs (4624/4625/5140) from engineering workstations and servers. OT/ICS: the deployed monitoring platforms (Claroty xDome, Dragos, Nozomi Guardian, Armis Centrix, Tenable OT, Forescout eyeInspect), historian and SCADA alarm records, controller configuration/firmware change logs, and SNMP interface counters and traps from the gateway-facing switch and reachable controllers. Node-RED application logs: the admin HTTP access log and the flow revision history on each gateway.

External attack surface: the passive internet-scan indices queried read-only (Shodan, Censys, Netlas), the CISA Known Exploited Vulnerabilities catalog, and the organization's authoritative public IP ranges and cloud asset inventories — the last of which is required for attribution; without a complete public-IP and cloud inventory the exposure determination in Hypothesis 1 cannot be made and must be reported Non-Conclusive rather than clean.

#### Detection Signatures

**SIGMA rule 1** — Node-RED spawning a shell/downloader on Linux (process\_creation):

`title: Node-RED Process Spawning Shell or Downloader on Linux id: 6f1d2a7c-4b3e-4c21-9a6e-2f8b1c0d4e5a status: experimental description: Detects the Node-RED runtime spawning a shell or download utility, consistent with a malicious flow exec node executing OS commands (CVE-2026-58115). references: - https://cert-portal.siemens.com/productcert/html/ssa-834709.html author: 1898 & Co. date: 2026/11/04 logsource: product: linux category: process_creation detection: selection: ParentImage|endswith: '/node' Image|endswith: - '/sh' - '/bash' - '/wget' - '/curl' condition: selection falsepositives: - Legitimate flows that intentionally shell out; baseline per deployment level: high`

 

**SIGMA rule 2** — Executable written to a memory-backed or temp directory (file\_event):

`title: Executable Written to /dev/shm or /tmp on OT Gateway id: 2b8c9e14-7a6d-4f03-8c1b-5d9e3a6f2c7b status: experimental description: Detects an executable file created in /dev/shm or /tmp, consistent with the bot-linux-amd64 payload staged at /dev/shm/.b (CVE-2026-58115 post-exploitation). references: - https://www.cisa.gov/news-events/ics-advisories/icsa-26-237-03 author: 1898 & Co. date: 2026/11/04 logsource: product: linux category: file_event detection: selection: TargetFilename|re: '/(dev/shm|tmp)/' condition: selection falsepositives: - Package managers and build tooling staging temp binaries; scope to OT gateways level: high`

 

**SIGMA rule 3** — Outbound connection from the gateway to the payload host (network\_connection):

`title: OT Gateway Outbound Connection to Known Node-RED Payload Host id: 9c3f5a2d-1e4b-4a8c-b7d6-0f2e8c1a3b4d status: experimental description: Detects an outbound connection to the payload-hosting infrastructure observed delivering the Node-RED Linux bot (CVE-2026-58115). references: - https://cert-portal.siemens.com/productcert/html/ssa-834709.html author: 1898 & Co. date: 2026/11/04 logsource: category: network_connection detection: selection: DestinationIp: - '85.215.73.250' condition: selection falsepositives: - Re-use of the hosting provider's address space by benign services; corroborate with payload artifacts level: high`

 

**Snort/Suricata rule 1** — inbound POST to the Node-RED /flows admin endpoint (plaintext HTTP on 1880; the sensor sees the URI directly):

`alert tcp any any -> $HOME_NET 1880 (msg:"OT NODE-RED Unauthenticated POST to /flows admin endpoint (CVE-2026-58115)"; flow:established,to_server; http.method; content:"POST"; http.uri; pcre:"/\/flows/"; classtype:attempted-admin; sid:1000001; rev:1; reference:url,cert-portal.siemens.com/productcert/html/ssa-834709.html;)`

 

**Snort/Suricata rule 2** — outbound retrieval of the Linux bot payload:

`alert tcp $HOME_NET any -> any any (msg:"OT NODE-RED Download of Linux bot payload (CVE-2026-58115)"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"bot-linux-amd64"; nocase; classtype:trojan-activity; sid:1000002; rev:1; reference:url,www.cisa.gov/news-events/ics-advisories/icsa-26-237-03;)`

 

The following YARA rule targets the dropped Linux bot and its staging artifacts on disk. It ORs the payload filename, the exact hidden drop path, and the two helper-script/process names into a single string set and fires on any one, because post-exploitation may leave only a subset of these on a given host; the payload-host IP is included so a configuration or log file referencing the download location also matches. There is no decoded-literal AND trap here — every string is a surface artifact present verbatim in the published indicators.

`rule NodeRED_Linux_Bot_Dropper { meta: description = "Node-RED (CVE-2026-58115) Linux bot payload and staging artifacts" author = "1898 & Co." date = "2026-11-04" reference = "https://cert-portal.siemens.com/productcert/html/ssa-834709.html" strings: $f1 = "bot-linux-amd64" ascii // dropped Linux bot binary name $f2 = "/dev/shm/.b" ascii // hidden in-memory drop path $f3 = "wget.sh" ascii // staging/download helper script $f4 = ".kworker" ascii // masquerading process/file name $n1 = "85.215.73.250" ascii // payload-hosting server condition: any of them }`

 

The following YARA rule targets a malicious Node-RED flow definition at rest (flows\_\*.json or a backup). It requires BOTH an exec/daemon node type AND a shell-download command fragment in the same file, so an ordinary flow that merely contains an exec node for legitimate automation does not match on the node type alone; the two-condition AND is the false-positive control.

`rule NodeRED_Malicious_Flow { meta: description = "Malicious Node-RED flow wiring an exec node to a shell download (CVE-2026-58115)" author = "1898 & Co." date = "2026-11-04" reference = "https://www.cisa.gov/news-events/ics-advisories/icsa-26-237-03" strings: $node = "\"type\":\"exec\"" ascii // exec node present in the flow $cmd1 = "wget" ascii $cmd2 = "curl" ascii $cmd3 = "/dev/shm" ascii $cmd4 = "chmod +x" ascii condition: $node and any of ($cmd*) }`

 

The following standing rule targets credential-dumping tooling in process memory and is included because Hypothesis 4 involves lateral movement (T1021). It covers the four classic Windows LSASS-access tool families plus a catch-all memory-read branch. Scope note: this rule targets Windows LSASS tooling and will NOT match Linux-specific credential theft (T1003.007 /proc scraping) — run it against the Windows engineering-workstation process pool the gateway can reach, not the Linux gateway itself; SeDebugPrivilege is required to scan LSASS, and CrowdStrike Falcon RTR can execute it on remote hosts.

`rule Credential_Dump_Tool_Memory_Artifacts { meta: description = "Credential-dumping tool artifacts in process memory (Windows LSASS)" author = "1898 & Co." date = "2026-11-04" strings: $mk1 = "sekurlsa::logonpasswords" ascii nocase $mk2 = "lsadump::sam" ascii nocase $mk3 = "privilege::debug" ascii nocase $mk4 = "mimikatz" ascii nocase wide $wce1 = "wce.exe" ascii nocase $gsec = "gsecdump" ascii nocase $cs1 = "MiniDump" ascii $cs2 = "comsvcs" ascii nocase $api1 = "NtReadVirtualMemory" ascii $api2 = "ReadProcessMemory" ascii $lsass = "lsass.exe" ascii nocase condition: any of ($mk*) or ($wce1 and $lsass) or $gsec or ($cs1 and $cs2 and $lsass) or (($api1 or $api2) and $lsass and any of ($mk*, $wce1, $gsec)) }`

 

#### Indicators of Compromise

**Network:** inbound HTTP POST to TCP/1880 /flows on a gateway from a non-engineering source; the scanner source address 4.201.105.116 (opportunistic mass-scanning origin in a major cloud provider's space); outbound connections from a gateway to the payload host 85.215.73.250; any outbound connection from a gateway to an unfamiliar external host immediately after a /flows POST. Host/operational: an executable written to /dev/shm or /tmp (notably /dev/shm/.b), the filenames bot-linux-amd64, wget.sh, and .kworker; unexpected Node-RED flow revision updates; inject, exec, or http-in nodes added without a change record; and a Node-RED process (node) spawning sh, bash, wget, or curl. OT-operational (behavioral, scoped to this hunt): a gateway initiating remote-access or industrial-protocol sessions into the control zone outside its established peer baseline; a controller reachable from the gateway showing a configuration/firmware change or a setpoint excursion with no corresponding operator action or work order.

External exposure: a SIMATIC IoT2050 / Node-RED editor service reachable from the internet in a declared public range, corroborated across ≥2 passive indices and attributed by ≥2 ownership signals, is itself an indicator warranting Hypothesis-2/3/4 confirmation on that device.

#### False Positive Baseline

1\. Legitimate Node-RED flows that intentionally use an exec node to run local automation — baseline the approved flow set per gateway and suppress known-good exec nodes by their command and deploy history.

2\. Engineering or maintenance hosts legitimately posting flow updates to /flows during a documented change window — correlate every POST against the change-management record and the source address before escalating.

3\. Package managers, build tooling, and update agents writing temporary executables to /tmp on the gateway's Industrial OS — scope the /dev/shm and /tmp file-write detections to unexpected parents (node) and to binaries that then execute or beacon.

4\. Benign services re-using the payload host's provider address space — an outbound connection to 85.215.73.250 is corroborated by a matching payload artifact or a preceding /flows POST before it is treated as confirmed.

5\. EASM misattribution — a Node-RED instance on shared hosting, a CDN, or a managed-cloud range that is not actually the organization's asset; never report an external hit without ≥2 independent ownership signals, and treat honeypots (which cluster exactly where OT findings look most promising) as a distinct false-positive class.

#### Escalation Criteria

1\. Any POST to the Node-RED /flows admin endpoint from a source outside the approved engineering/change-management set on an affected gateway.

2\. Any inject, exec, or http-in node present in a gateway's current flow set that cannot be matched to an approved flow.

3\. Any YARA hit on NodeRED\_Linux\_Bot\_Dropper against /dev/shm, /tmp, or the gateway filesystem.

4\. Any YARA hit on NodeRED\_Malicious\_Flow against a flows\_\*.json file or its backup on any gateway.

5\. Any YARA hit on Credential\_Dump\_Tool\_Memory\_Artifacts against a Windows engineering-workstation process reachable from a gateway.

6\. Any outbound connection from a gateway to 85.215.73.250, or to any external host fetching an artifact named bot-linux-amd64 or wget.sh.

7\. Any connection from a gateway address into the control zone on a remote-access or industrial-control port that is not in the gateway's established baseline, or any controller configuration/firmware change or setpoint excursion reachable from the gateway with no operator action.

8\. Any two-engine-corroborated, in-range external exposure of a Node-RED/IoT2050 service, exposure that spans the 2026-08-11→present window, or a CISA KEV match for CVE-2026-58115.

#### Hunt Completion Criteria and Reporting

The hunt is complete when Hypothesis 1 has been run first and its exposure set fed into Hypotheses 2–4, and every hypothesis has been executed across the full window on all in-scope gateways and reachable hosts for which telemetry exists. The report must give a verdict per hypothesis using that hypothesis's Verdict criteria, and record every limitation with its direction — for example: an IDS on a plaintext Node-RED interface sees the /flows URI only where the sensor is in the traffic path; a gateway without the CrowdStrike Falcon Linux sensor emits no CQL telemetry of its own, so a CQL zero for that device is Non-Conclusive, not clean; xDome Communication Analysis under-reports both sessions and bytes and must be reconciled against an independent source; the EASM sweep sees only what the indices observed, and absence from an index is not absence of exposure.

Make absence claims only from a single-predicate filter (filter for the indicator and count), never by reading a distribution table, and quote only queries whose LogScale status reads Done — a progressively-rendered aggregate looks final while still partial, so capture the status bar in every screenshot. Report every leg whose control query returned zero or was not run as Non-Conclusive, naming the missing input (gateway sensor coverage, forwarded auditd logs, OT-platform flow coverage, a complete public-IP inventory). Recommend running the Hypothesis-1 external-exposure sweep as a recurring control, since where the vendor fix cannot be applied immediately, removing internet exposure is one of only two available mitigations.

#### Advisory IoC Reference

| IOC Type | IOC |
| --- | --- |
| CVE | CVE-2026-58115 \| CVSS v4.0 10.0 \| SIMATIC IoT2050 Advanced \< V4.3.4.1 \| Missing authentication on the Node-RED HTTP interface enables unauthenticated remote code execution with maximum privileges (CWE-306) |
| Threat Actor | None attributed — activity consistent with opportunistic, botnet-oriented mass scanning; no named group, APT cluster, or government attribution in any advisory |
| Malware | bot-linux-amd64 \| Linux bot (AMD64) \| Payload downloaded by a malicious Node-RED exec flow to /dev/shm/.b and executed; post-launch behavior not publicly confirmed |
| Network IOC | IP: 4.201.105.116 |
| Network IOC | IP: 85.215.73.250 |
| File IOC | Filename: bot-linux-amd64 |
| File IOC | Path: /dev/shm/.b |
| File IOC | Filename: wget.sh |
| File IOC | Filename: .kworker |
| Behavioral | Unauthenticated HTTP POST to /flows on Node-RED TCP/1880 from a non-engineering source |
| Behavioral | Node-RED process (node) spawning sh, bash, wget, or curl |
| Behavioral | Executable written to /dev/shm or /tmp (e.g. /dev/shm/.b) then executed |
| Behavioral | Inject, exec, or http-in node added to a gateway flow set with no change record |
| Behavioral | Gateway initiating remote-access or industrial-protocol sessions into the control zone outside its established peer baseline |

[Threat Hunt](https://1898advisories.burnsmcd.com/tag/threat-hunt)

*The information in this cybersecurity advisory is provided "as is" for informational purposes only. 1898 & Co. does not provide any warranties or guarantees of any kind regarding this information. You assume all risks if you choose to rely on this information. In no event shall 1898 & Co. or its contractors or subcontractors be liable for any damages including, but not limited to, direct, indirect, special or consequential damages, arising out of, resulting from, or in any way connected with, this information, whether or not based upon warranty, contract, tort, or otherwise, whether or not arising out of negligence, and whether or not injury was sustained from, or arose out of the results of, or reliance upon the information*

*1898 & Co. does not endorse any product or service, except as expressly stated otherwise. Any reference to products or processes does not constitute or imply 1898 & Co.’s endorsement or recommendation.*

Subscribe

✕ Close

 

[Accessibility](https://1898andco.burnsmcd.com/accessibility)  |  [Privacy Statement](https://1898andco.burnsmcd.com/privacy)

© 2026 1898 & Co., a part of Burns & McDonnell. All Rights Reserved.

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "The 1898 & Co. Team",
    "url" : "https://1898advisories.burnsmcd.com/author/1898-co-team"
  },
  "dateModified" : "2026-11-04T18:05:07.121Z",
  "datePublished" : "2026-11-04T18:05:07.000Z",
  "headline" : "Threat Hunt Plan: Node-RED Missing Authentication on Siemens SIMATIC IoT2050 Advanced — Unauthenticated RCE and Linux Malware Deployment",
  "mainEntityOfPage" : {
    "@id" : "https://1898advisories.burnsmcd.com/threat-hunt-plan-node-red-missing-authentication-on-siemens-simatic-iot2050-advanced-unauthenticated-rce-and-linux-malware-deployment",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "//cdn2.hubspot.net/hub/477837/file-2585615236-jpg/Logo_1_Primary_2Color1.jpg"
    },
    "name" : "Burns & McDonnell Engineering Co"
  }
}
```