← All playbooks
CriticalExploited vuln · 2026-11-09

Node-RED / Siemens IoT2050 CVE-2026-58115 (CVSS 10): unauthenticated flow deployment is being exploited for Linux bots and webshells

SockAnalyst · Security+ certified analyst.

What happened

CVE-2026-58115 (CVSS 10.0) is a missing-authentication flaw in the Node-RED HTTP interface on Siemens SIMATIC IoT2050 devices running Industrial OS with Node-RED installed. An unauthenticated remote attacker can create malicious flows and run code with maximum privileges. Siemens published advisory SSA-834709 in August 2026 and fixed it in V4.3.4-1. VulnCheck reported that on October 30, 2026 one of its honeypots caught a complete exploit: a single POST /flows deployed an inject-to-exec flow that downloaded a Linux bot, saved it in memory-backed storage and ran it. By November 1 it had seen about 15 more attempts from the same IP delivering other payloads, including persistent webshell-style flows that expose an HTTP endpoint wired to an exec node. Researchers say attackers are scanning for Node-RED instances without adminAuth and exploiting them automatically. Node-RED ships with authentication off by default, so non-Siemens installs without adminAuth are exposed to the same style of attack. VulnCheck could not retrieve the payloads, so the bot's function is unknown. This flaw was not listed on the CISA KEV catalog as of our check.

Who's affected

Siemens SIMATIC IoT2050 Advanced, Basic, M.2 and SM devices on Industrial OS with Node-RED installed and firmware older than V4.3.4-1 (Siemens lists all four models). Researchers also warn that any internet-reachable Node-RED editor or admin API without adminAuth, including in OT and IoT environments, can be abused the same way.

✅ Fix / patch

  • Update affected SIMATIC IoT2050 devices to V4.3.4-1 or later (Siemens SSA-834709).
  • If you cannot update, uninstall Node-RED or harden it per Siemens: enable HTTPS, require credential or OAuth/OpenID authentication for the editor and admin API, and put HTTP nodes and the dashboard behind basic authentication.
  • Set adminAuth on every Node-RED instance and keep the editor off the internet; restrict it to a management VLAN or VPN.
  • Review deployed flows for unexpected exec, function or http-in nodes, and rebuild from known-good flows if anything unexpected is found. Hidden files in /dev/shm and /tmp mean a reboot will not remove a flow-based backdoor.

🔎 Quick hunt check

Published indicators (defanged): payload server 85.215.73[.]250 (bot-linux-amd64, wget.sh); 45.194.90[.]57:38472 (.sys_update); dropped files /dev/shm/.b and /tmp/.kworker. Exploitation arrived as one POST /flows from an IP in Microsoft's AS8075. Hunt for POST /flows or /flows requests to Node-RED from non-admin sources, outbound wget/curl from the Node-RED process, and new http-in endpoints such as /cmd.

MITRE ATT&CK: T1190, T1059.004, T1105, T1505.003, T1036.005

IOCs

  • IP addresses: 85.215.73[.]250, 45.194.90[.]57
  • Files / paths: /dev/shm/.b, /tmp/.kworker, bot-linux-amd64, wget.sh, .sys_update

Hunt queries

Starting points built only from published indicators. Field names vary; tune before use.

(index=web OR index=proxy OR index=network) (http_method=POST OR method=POST) (uri_path="/flows" OR uri_path="/flow" OR uri_path="/auth/*")
| stats count min(_time) as first max(_time) as last values(status) as status values(src_ip) as src_ip by dest, uri_path
| append [ search index=edr (process_name IN ("wget","curl") OR process IN ("wget","curl")) ("85.215.73.250" OR "45.194.90.57" OR "/dev/shm/.b" OR "/tmp/.kworker" OR "bot-linux-amd64" OR "wget.sh" OR ".sys_update") | stats count by host, user, process, command ]
// POST /flows to Node-RED from unexpected sources plus downloader activity matching VulnCheck's published CVE-2026-58115 payload names and servers
let iocIPs = dynamic(["85.215.73.250","45.194.90.57"]);
let web = CommonSecurityLog
| where TimeGenerated > ago(30d)
| where RequestMethod =~ "POST" and RequestURL has "/flows"
| project TimeGenerated, SourceIP, DestinationIP, RequestURL, DeviceVendor;
let net = CommonSecurityLog
| where TimeGenerated > ago(30d)
| where DestinationIP in (iocIPs) or SourceIP in (iocIPs)
| project TimeGenerated, SourceIP, DestinationIP, DestinationPort, Activity;
let proc = Syslog
| where TimeGenerated > ago(30d)
| where SyslogMessage has_any ("/dev/shm/.b","/tmp/.kworker","bot-linux-amd64","wget.sh",".sys_update")
| project TimeGenerated, Computer, SyslogMessage;
union web, net, proc
// POST /flows to Node-RED, traffic to the two published payload servers, and the published dropped file names

See all hunt queries →

⏱ CISA deadline

Not in CISA KEV as of Nov 14, 2026.

Sources

Related playbooks

Get the Weekly KEV & Hunt Pack free — plus the daily SOC brief.

Weekly email; daily brief on the website.

Subscribe free

Read the free weekly pack →