A phone call that skips the receptionist and rings straight into the server room with root access
CVE-2026-82104 affects Teltonika RUTOS devices running 7.22 through 7.24.2 across RUT, RUTX, RUTM, RUTC, ATRM, TAP, CAP, OXA, DAP, TRB, OTD, and EBG families, and TSWOS devices running 1.9 through 1.10. The official record describes an unauthenticated user directly invoking LUA functions through the device's web/API surface, bypassing the validation and workflow checks that normal API requests would perform. Because the request skips the approved flow, it can lead to operating system command execution on the router or gateway itself.
There is no vendor CVSS score attached to this CVE, but the official description is explicit: pre-authentication, direct LUA invocation, OS command execution on network appliances. These are Teltonika routers and switch/gateway devices that are commonly placed at remote sites and industrial edge locations. The absence of a vendor score should not lower urgency. The correct severity is CRITICAL, with an assessed CVSS 9.8 because the vulnerable component is a network-edge device with a high-value role in the path between remote clients, IT networks, and operational networks.
4 steps from start to impact.
Identify an exposed Teltonika management interface
- Attacker can reach the device management port over the internet, cellular network, or an untrusted segment
- Target is running RUTOS 7.22–7.24.2 or TSWOS 1.9–1.10
- If remote management is disabled or restricted to a VPN/jump host, initial internet reachability is blocked
- Devices on private APNs or isolated industrial VLANs reduce direct exposure
Call an unauthenticated LUA function directly
- No credentials or valid session required
- Attacker knows or discovers the direct LUA endpoint or function name
- Exact endpoint names may vary by firmware and model, but the vulnerability description indicates direct unauthenticated invocation is the core issue
- A custom WAF or reverse proxy might block some requests if the endpoint is already profiled
Achieve OS command execution on the device
- LUA function passes attacker-controlled arguments into an OS command execution primitive
- Underlying management process has sufficient privileges to execute system commands
- If the management process runs as an unprivileged user, impact is limited to that user; however, network-gear management daemons are usually high-privilege
- Physical access is not required, and no user interaction is needed
Pivot into the trusted LAN or operational network
- Attacker can maintain access long enough to inspect configs and establish a tunnel
- Critical assets are reachable through the router's LAN/OT interfaces
- Strong network segmentation and host-based firewalls can limit lateral movement from the router
- Outbound firewall rules and DNS monitoring can block or detect reverse C2 tunnels
- Strong passwords or MFA do not stop this vulnerability because the direct LUA endpoint is reachable before authentication.
- HTTPS/TLS for the management UI does not prevent exploitation; it only encrypts the malicious request and can blind detection tools unless inline TLS inspection is in place.
- A generic web application firewall may not help unless it already has a signature for the direct LUA endpoint; the request can look like a legitimate API call.
The supporting signals.
| In-the-wild status | No confirmed mass exploitation in public sources as of disclosure, but the pre-auth primitive makes rapid weaponization likely. |
|---|---|
| PoC availability | Not yet indexed on pocindex.io as of assessment; given the bug class, expect functional PoCs shortly. |
| EPSS score | Not available in EPSS at time of assessment; pre-auth network exposure predicts a high future percentile. |
| KEV status | Not present in CISA KEV as of disclosure. |
| CVSS vector | Assessed as CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8. |
| Affected versions | RUTOS 7.22 through 7.24.2 across RUT, RUTX, RUTM, RUTC, ATRM, TAP, CAP, OXA, DAP, TRB, OTD, EBG; TSWOS 1.9 through 1.10 across SWM and TSW. |
| Fixed versions | Vendor advisory should be checked for exact patched releases; Teltonika typically backports to the next maintenance branch such as RUTOS 7.24.3 and TSWOS 1.10.1. |
| Scanning/exposure data | Shodan/Censys regularly enumerate thousands of internet-facing Teltonika RUT and TRB devices worldwide; many are used for remote equipment and cellular site access. |
| Disclosure date | 2026-10-30 |
| Reporting researcher/org | Not publicly attributed; likely Teltonika internal or a coordinated researcher. |
Sources.
Why this verdict
- Unauthenticated remote attack surface: the chain requires no credentials, no valid session, and no user interaction; an internet-exposed device is exploitable immediately.
- Direct OS command execution: bypassing LUA validation leads to shell execution on the device OS, enabling configuration exfiltration, credential reuse, persistence, and traffic interception.
- Deployment-role multiplier: Teltonika RUT/TRB/TSW devices are canonically network edge and industrial gateways. Compromise creates a bridge into trusted LAN, VPN, and potentially OT/SCADA traffic flows — domain- or fleet-scale impact, not just a single host.
- Widely exposed installed base: these devices are frequently placed on WAN or cellular interfaces for remote site management, so the vulnerable population includes a meaningful share of publicly reachable appliances.
Why not higher?
There is no severity bucket above CRITICAL. The assessed 9.8 is already within the top range. We reserve a 10.0 for evidence of a self-propagating worm or immediate multi-vendor safety impact; this vulnerability requires even trivial per-device interaction, but there is no observed autonomous propagation yet.
Why not lower?
Although the CVE is not yet KEV-listed, the affected component is a canonical network edge appliance. The documented chain succeeds from unauthenticated remote access to full device control. Limiting exposure can lower exploitability, but the installed role includes public-facing industrial routers, so the role-multiplier floor remains CRITICAL.
Crowdsourced verification payload.
Run from an auditor workstation or management host that can reach the target router over HTTP/HTTPS. Invoke with python3 check_cve_2026_82104.py <host_or_ip>. The script uses only the Python standard library and needs no special privileges on the scanner; on the target it only requires the device management interface to be reachable. It performs version detection and outputs VULNERABLE, PATCHED, or UNKNOWN based on RUTOS/TSWOS firmware banners.
#!/usr/bin/env python3
"""Detect affected Teltonika RUTOS/TSWOS versions for CVE-2026-82104."""
import argparse, re, ssl, sys, urllib.request
def fetch(url):
ctx = ssl._create_unverified_context()
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
try:
with urllib.request.urlopen(req, timeout=6, context=ctx) as r:
return r.read().decode('utf-8', errors='ignore')
except Exception:
return ''
def parse_version(text):
"""Return (major, minor, patch) from a RUTOS/TSWOS banner if present."""
m = re.search(r'(RUTOS|TSWOS)[^\d]{0,30}?(\d{1,2})\.(\d{1,2})\.(\d{1,2})', text, re.I)
if m:
return m.group(2), m.group(3), m.group(4)
m = re.search(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})', text)
return m.groups() if m else (None, None, None)
def is_vulnerable(major, minor, patch):
try:
v = (int(major), int(minor), int(patch))
except Exception:
return False
# RUTOS 7.22.0 - 7.24.2 inclusive
if 7 == v[0] and (7, 22, 0) <= v <= (7, 24, 2):
return True
# TSWOS 1.9.x - 1.10.x inclusive
if 1 == v[0] and 9 <= v[1] <= 10:
return True
return False
def main():
ap = argparse.ArgumentParser()
ap.add_argument('host')
args = ap.parse_args()
host = args.host
for base in (f'http://{host}/', f'https://{host}/'):
text = fetch(base)
if not text:
continue
major, minor, patch = parse_version(text)
if major is not None:
print(f'Found version {major}.{minor}.{patch} at {base}')
if is_vulnerable(major, minor, patch):
print('VULNERABLE')
else:
print('PATCHED')
return 0
print('UNKNOWN: could not determine firmware version')
return 1
if __name__ == '__main__':
sys.exit(main())