Threat Overview
Ridge Security disclosed CVE-2026-42542 on September 28, 2026. The flaw is an integer-underflow condition in TDengine’s pre-authentication RPC message parsing. An unauthenticated attacker with network access to the default TCP/6030 RPC service can send one malformed packet whose declared message length is smaller than the fixed header, causing attacker-influenced length arithmetic, heap corruption, and a remote taosd crash. Ridge confirms denial of service; it explicitly does not claim remote code execution. Affected TDengine releases are 3.4.0.0 through 3.4.1.5. Version 3.4.1.6 fixes the issue. TDengine is commonly used for industrial, IoT, energy, automotive, device-monitoring, and time-series workloads, where database outages can remove operational visibility and create gaps in historical telemetry. Ridge has a working proof of concept but has not published it. No in-the-wild exploitation or public exploit code was known at disclosure.
References
- Ridge Security — One Packet Can Take Down the Database Behind Industrial Operations — September 28, 2026.
- GitHub Advisory GHSA-vg95-j2hf-hvjx — vendor-coordinated advisory.
- Dark Reading — One Packet Can Crash OT Servers in Industrial Sectors — September 28, 2026.
Impacted Systems
- Vendor/product: TDengine open-source time-series database,
taosdRPC service. - Affected versions: 3.4.0.0 through 3.4.1.5.
- Fixed version: 3.4.1.6 or later.
- Platform: Linux-based self-managed deployments and TDengine embedded in appliances or OEM/integrator solutions; exact operating-system distributions are not the vulnerability boundary.
- Service role: Database node receiving TDengine RPC traffic on TCP/6030 by default.
- Prerequisite: Network reachability to the RPC service; no authentication or established session is required.
- Exposure: Internet-facing TCP/6030, flat OT/device networks, or broad internal access materially increase risk.
- Unaffected: Versions earlier than 3.4.0.0 and 3.4.1.6+ are outside the published affected range; other TDengine services are not claimed vulnerable by this CVE.
Why this matters
The exploit cost is low, requires a single packet, and targets a database commonly used for operational telemetry. Even without confirmed exploitation, an unexpected crash can blind industrial monitoring, dashboards, analytics, and anomaly detection. Embedded deployments may not be represented in normal software inventory.
Exploitation Status
Ridge Security confirmed the vulnerability with a private proof of concept and coordinated a fix. As of September 28, Ridge reported no exploitation telemetry and no public exploit code. Detection guidance is derived from the vulnerability mechanics rather than observed campaign behavior. No attacker IOCs are available.
What this hunt looks for
Inbound TCP/6030 access from unusual sources, repeated short sessions and low-byte connections, public-source fan-out, taosd crashes or restart loops, endpoint-observed restarts following port 6030 traffic, and gaps in previously steady taosd Syslog reporting.
Required logs
Firewall, NDR, or endpoint network telemetry for inbound TCP/6030 in CommonSecurityLog or DeviceNetworkEvents; Microsoft Defender for Endpoint DeviceProcessEvents; and Linux Syslog carrying taosd or service-manager events. Packet capture or protocol-aware IDS telemetry is needed to validate malformed TDengine message lengths.
Hunt 1 — External or unexpected access to TDengine RPC port 6030
union isfuzzy=true CommonSecurityLog, DeviceNetworkEvents
| where TimeGenerated > ago(30d)
| extend SrcIP=tostring(coalesce(column_ifexists("SourceIP",""),column_ifexists("RemoteIP",""))), DstIP=tostring(coalesce(column_ifexists("DestinationIP",""),column_ifexists("LocalIP",""))), DstPort=toint(coalesce(column_ifexists("DestinationPort",0),column_ifexists("LocalPort",0))), Action=tostring(coalesce(column_ifexists("DeviceAction",""),column_ifexists("ActionType","")))
| where DstPort == 6030
| where not(ipv4_is_private(SrcIP))
| project TimeGenerated, SrcIP, DstIP, DstPort, Action, DeviceName=column_ifexists("DeviceName",""), DeviceVendor=column_ifexists("DeviceVendor",""), DeviceProduct=column_ifexists("DeviceProduct","")
| order by TimeGenerated desc
Hunt 2 — One source probing multiple TDengine hosts
CommonSecurityLog
| where TimeGenerated > ago(30d) and DestinationPort == 6030
| summarize Targets=dcount(DestinationIP), Attempts=count(), TargetIPs=make_set(DestinationIP,50), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by bin(TimeGenerated,10m), SourceIP
| where Targets >= 3 or Attempts >= 20
| order by Targets desc
Hunt 3 — New source addresses connecting to TCP/6030
let Baseline = CommonSecurityLog
| where TimeGenerated between (ago(30d) .. ago(1d)) and DestinationPort == 6030
| summarize by SourceIP, DestinationIP;
CommonSecurityLog
| where TimeGenerated > ago(1d) and DestinationPort == 6030
| join kind=leftanti Baseline on SourceIP, DestinationIP
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Connections=count(), Actions=make_set(DeviceAction,10) by SourceIP, DestinationIP, DestinationPort, DeviceVendor, DeviceProduct
| order by Connections desc
Hunt 4 — Short-lived or low-byte connections to TCP/6030
CommonSecurityLog
| where TimeGenerated > ago(30d) and DestinationPort == 6030
| extend Sent=tolong(column_ifexists("SentBytes",0)), Received=tolong(column_ifexists("ReceivedBytes",0))
| where Sent between (1 .. 512) and Received < 512
| summarize Connections=count(), TotalSent=sum(Sent), TotalReceived=sum(Received), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by SourceIP, DestinationIP, DeviceAction
| order by Connections desc
Hunt 5 — taosd segmentation faults, memory corruption, or core dumps
Syslog
| where TimeGenerated > ago(30d)
| where ProcessName in~ ("kernel","systemd-coredump","taosd","systemd") or SyslogMessage has "taosd"
| where SyslogMessage has_any ("segfault","segmentation fault","core dumped","core dump","SIGSEGV","invalid memory","heap corruption","terminated abnormally")
| project TimeGenerated, Computer, Facility, SeverityLevel, ProcessName, SyslogMessage
| order by TimeGenerated desc
Hunt 6 — Repeated taosd restarts or failures
Syslog
| where TimeGenerated > ago(30d)
| where SyslogMessage has "taosd" and SyslogMessage has_any ("Started","Starting","Stopped","Failed","Main process exited","Scheduled restart job","restart counter")
| summarize Events=count(), Messages=make_set(SyslogMessage,20), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by bin(TimeGenerated,15m), Computer
| where Events >= 3
| order by Events desc
Hunt 7 — Endpoint-observed inbound 6030 connection followed by a taosd restart
let Connections = DeviceNetworkEvents
| where TimeGenerated > ago(30d) and LocalPort == 6030
| project DeviceId, DeviceName, ConnectionTime=TimeGenerated, RemoteIP, RemotePort, InitiatingProcessFileName;
let Starts = DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where FileName in~ ("taosd","taosd.exe")
| project DeviceId, StartTime=TimeGenerated, StartCommand=ProcessCommandLine, InitiatingProcessFileName;
Connections
| join kind=inner Starts on DeviceId
| where StartTime between (ConnectionTime .. ConnectionTime+5m)
| project ConnectionTime, StartTime, DeviceName, RemoteIP, RemotePort, StartCommand, InitiatingProcessFileName
| order by ConnectionTime desc
Hunt 8 — Gaps in ingested taosd Syslog activity after prior steady reporting
let ActiveHosts = Syslog
| where TimeGenerated between (ago(24h) .. ago(1h)) and (ProcessName =~ "taosd" or SyslogMessage has "taosd")
| summarize BaselineEvents=count(), LastBaseline=max(TimeGenerated) by Computer
| where BaselineEvents >= 10;
let Recent = Syslog
| where TimeGenerated > ago(1h) and (ProcessName =~ "taosd" or SyslogMessage has "taosd")
| summarize RecentEvents=count(), LastRecent=max(TimeGenerated) by Computer;
ActiveHosts
| join kind=leftouter Recent on Computer
| extend RecentEvents=coalesce(RecentEvents,0)
| where RecentEvents == 0
| project Computer, BaselineEvents, LastBaseline, RecentEvents
Detection Notes
- Hunts 5 and 6 are the highest-signal host indicators because the confirmed outcome is a crash. They still require correlation with unexpected network access to distinguish attack from software instability.
- TCP connection logs cannot prove the packet’s declared
msgLenwas smaller than the header. Packet capture, IDS, or protocol-aware telemetry is required for that condition. - Hunt 4 depends on byte counters and may match health checks or failed legitimate handshakes. Baseline known TDengine clients.
- A single malicious packet may precede the crash by milliseconds and may not create a full session record.
taosdlogging may be absent from Syslog or may stop because the database, host, or connector failed. Confirm the ingestion path before interpreting a gap.- Do not escalate a crash as exploitation without considering application defects, resource exhaustion, maintenance, and host instability.